Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Hello fellow monks!
I have a script that typically runs in ~10 mins (I have tried to make it faster as much as I can and I think I have reached the upper limit of it, at least based on my skills).
I came across this:
http://perltricks.com/article/61/2014/1/21/Make-your-code-run-faster-w +ith-Perl-s-secret-turbo-module

1. Has anyone here used it?
2. Is it easy to implement without changing one's code internally?
3. Does it make that much of a difference indeed?

2014-02-24 Retitled by GrandFather, as per Monastery guidelines

Replies are listed 'Best First'.
Re: Does anyone know about the Multi-CPU Module
by Corion (Patriarch) on Feb 23, 2014 at 00:17 UTC

    You don't tell us why your script is slow. Until you've determined what is holding your script back, there is very little sense in throwing multiple CPUs at it. MCE will likely need a major rewrite of your script to make it work in parallel, and you haven't told us that your script is CPU bound.

    If you can compile your own Perl, compiling a Perl without thread support usually gives roughly 10% performance improvement.

    Using a different algorithm can speed up your program by large factors.

    Caching more data between runs can also speed up your program vastly, at the cost of disk space.

    First of all, you have to determine where your program is slow. Devel::NYTProf will likely help you there.

      Hm, it turned out that I was wrongly using the Switch function instead of the normal if-elsif one... Now the code is something like 80% faster, I guess no multi-threads are needed!
      Thank you!
      Hi Corion,

      MCE requiring a "major" rewrite is a strong phrase. Not all use-cases requires a "major" rewrite. Typically, changes are print to MCE->print or MCE->say. The other having to write an output iterator if wanting to preserve output order which is added code and not so much changing the original code.

      MCE::Loop can wrap serial code quite nicely, only changing a few lines.

      Serial code.

      my @input = 100..200; foreach (@input) { print "$_\n"; };

      MCE code.

      use MCE::Loop max_workers => 8, chunk_size => 1; my @input = 100..200; mce_loop { MCE->print("$_\n"); } @input;

      MCE::Map requires only a single line change. Replacing map with mce_map.

      use MCE::Map; use Time::HiRes 'sleep'; # for simulating work my @a = mce_map { sleep rand; $_ * 1.618 } 1 .. 100; print "@a\n";

        Sure - as long as your code is cleanly structured and basically functional code without side effects, that's no problem.

        As soon as you have global variables and iterate over them or state in the database, this does not apply anymore. For example the following construct will need a major rewrite of the logic because DBI statement handles do not survive fork():

        my $sth_items= $dbh->prepare(<<SQL); select * from myitems where date > '20140101'; SQL while(my $item= $sth_items->fetchrow()) { ... lengthy process for each item ... };

        You cannot easily apply mce_loop or mce_map there, because you don't want to fetch all rows into the process. So here, the program logic will need a major rewrite.