http://www.perlmonks.org?node_id=910436

I have been revisiting Perl recently; it has been more than 10 years since I made my last "serious" attempts at Perl development. Naturally, there is a lot to catch up with - especially the idea of "Modern Perl" as opposed to "Legacy Perl". I must admit that I'm not totally sold on the idea of opposing one with another; however I'm delighted to see that Perl is actively developed. It seems not only to be active but improving as well, and many respectable Perl hackers are advising to move forward to 5.10 and beyond.

Well that sounds very nice, but during my recent encounter with DBD::SQLite I got a new question: is the move worth it? I don't mind all the syntactic sugar - it's all very fine but even Perl 5.005 had it more than enough for me to study and master for another ten years. What I'm actually talking about is speed. We all know that Perl code may not be the best in terms of execution, and usually compare it to C - but what about comparing one version to another? Quick googling wasn't very resultative so I decided to set up a test bench and run some benchmarks on my own.

The script that was used in benchmarks is as follows:

use strict; use warnings; use Benchmark qw(cmpthese); ($_) = <DATA>; chomp; my @data = split /:/; cmpthese(100_000, { 'for-ind-eq' => sub { my @copy = @data; for (0..$#copy) { $copy[$_] = undef if $copy[$_] eq ''; } }, 'for-ind-match' => sub { my @copy = @data; for (0..$#copy) { $copy[$_] = undef if $copy[$_] =~ /^$/; } }, 'foreach-eq' => sub{ my @copy = @data; foreach (@copy) { $_ = undef if $_ eq ''; } }, 'foreach-match' => sub { my @copy = @data; foreach (@copy) { $_ = undef if /^$/; } }, 'map-eq' => sub { my @copy = @data; map { $_ = $_ eq '' ? undef : $_ } @copy; }, 'map-match' => sub { my @copy = @data; map { $_ = /^$/ ? undef : $_ } @copy; }, }); __DATA__ 4479:5509:7721:1743:7821::9119::9532::7095::5028:6179:2693:2133::4158: +7256:7960:::8094:1458:5739:7570:::5059:4926:4933:7378:3066:7916:6062: +::7671:399::::1010::3938:2278:8571:::2286::4740::4133::::2712::::2507 +::1579::4503:3889:1892:7667::::5676::::::8371:2258:372::2795:4126:215 +6:6580:5798:::8138::4545:7843:2231:4414:5792::6187::3488

While I cannot claim to cover all aspects of the language, this simple script does utilize some very basic and widely used language constructs: for/foreach loops, map, array manipulating, scalar comparison and pattern matching. In fact, I used this test script to answer a question that nagged me for ages: what is the best way to check an array of strings for empty strings? While the answer I got was predictable, performance comparison results were not.

I have used four version of Perl for this benchmark: 5.6.1 supplied with Solaris 9 x86 I'm working on (for hysterical raisins) and three custom built versions: 5.8.9, 5.10.1 and 5.14.1. I decided to skip 5.12.3 for I see no reason in testing it now that 5.14.1 is available. All custom builds were Configure'd with -des to ensure genuine vanilla flavor. All Perl versions are unthreaded.

The results are as follows (5.6.1 Benchmark output cut for clarity)

Perl 5.6.1
                 Rate map-match map-eq for-ind-match foreach-match for-ind-eq foreach-eq
map-match     15106/s        --    -8%          -25%          -34%       -36%       -42%
map-eq        16474/s        9%     --          -19%          -28%       -30%       -36%
for-ind-match 20243/s       34%    23%            --          -12%       -14%       -22%
foreach-match 22989/s       52%    40%           14%            --        -3%       -11%
for-ind-eq    23585/s       56%    43%           17%            3%         --        -9%
foreach-eq    25907/s       72%    57%           28%           13%        10%         --

Perl 5.8.9
                 Rate map-match map-eq for-ind-match for-ind-eq foreach-match foreach-eq
map-match     17730/s        --    -5%          -28%       -32%          -40%       -45%
map-eq        18587/s        5%     --          -25%       -29%          -37%       -43%
for-ind-match 24631/s       39%    33%            --        -6%          -17%       -24%
for-ind-eq    26110/s       47%    40%            6%         --          -11%       -20%
foreach-match 29499/s       66%    59%           20%        13%            --        -9%
foreach-eq    32468/s       83%    75%           32%        24%           10%         --

Perl 5.10.1
                 Rate map-match map-eq for-ind-match foreach-match for-ind-eq foreach-eq
map-match     10846/s        --   -10%          -19%          -34%       -39%       -46%
map-eq        12034/s       11%     --          -10%          -26%       -33%       -40%
for-ind-match 13333/s       23%    11%            --          -19%       -26%       -34%
foreach-match 16367/s       51%    36%           23%            --        -9%       -19%
for-ind-eq    17921/s       65%    49%           34%            9%         --       -11%
foreach-eq    20202/s       86%    68%           52%           23%        13%         --

Perl 5.14.1
                 Rate map-match map-eq for-ind-match foreach-match for-ind-eq foreach-eq
map-match     15038/s        --   -14%          -18%          -25%       -48%       -50%
map-eq        17513/s       16%     --           -4%          -13%       -39%       -42%
for-ind-match 18315/s       22%     5%            --           -9%       -36%       -39%
foreach-match 20040/s       33%    14%            9%            --       -30%       -33%
for-ind-eq    28818/s       92%    65%           57%           44%         --        -4%
foreach-eq    29940/s       99%    71%           63%           49%         4%         --

I must admit that I was quite surprised by results; I believe they speak for themselves. I don't know if that is the result of codebase revamping between 5.8 and 5.10, or any other reason; but it seems to me that it's premature to take "Modern Perl is always better" as a given. For some applications, it's not true yet. I do see a strong incentive for upgrade from 5.10.1 to 5.14.1 - the difference is too significant to ignore. As for 5.8.9 to 5.14.1... I'm not sold. Nothing I've seen in perldeltas would suggest that 5.8.9 is now obsolete to the point of being unusable, and this performance hit is very serious reason for me to postpone the upgrade.

All in all, I'd vote for deeper research in this matter. I will do more tests, time permitting. And offer a shy rebellious thought meanwhile: maybe it's worth it to revisit 5.8 and patch it up with the latest bugfixes other than security related?..

Regards,
Alex.

P.S. Coming back to the original question addressed by the benchmark: it is clearly seen that $_ eq '' is usually faster than /^$/. However, /^$/ looks and feels more Perlish - would it be beneficial to check this as a special case with regexp processing and optimize it away?

Replies are listed 'Best First'.
Re: Why "Modern Perl" is slower than "Legacy Perl"?
by moritz (Cardinal) on Jun 19, 2011 at 17:00 UTC
    Well that sounds very nice, but during my recent encounter with DBD::SQLite I got a new question: is the move worth it? I don't mind all the syntactic sugar - it's all very fine but even Perl 5.005 had it more than enough for me to study and master for another ten years.

    You seem to reduce the changes between perl 5.8 and 5.14 to two categories: speed and syntactic sugar.

    But there are lots of other changes between those versions, which IMHO make the upgrade very worthwhile, even if it comes with a slight speed penalty. If you upgrade from 5.8 to 5.14, you get for example:

    • A module installer that actually works most of the time
    • Lots of bug fixes
    • Support
    • The capability to install many modules. Quite a few of the modules that don't depend on 5.10 or newer directly do (often indirectly) depend on newer versions of core modules, and upgrading core modules has always been a delicate business.
    • A regex engine that doesn't segfault when you provide it with too long strings
    • Greatly improved Unicode handling
    • Unicode handling in the Pod tools
    • Warnings in the case of undefined behavior (for example my in statement-modifying conditionals)
    • Trie regex optimizations that speed up alternatives of literal strings by a big amount

    Plus lots of features that you probably discount as "syntactic sugar".

    That said, I'd be interested in a performance comparison for some real-world applications that not only loop over arrays and assign undef to some elements, but do some more interesting stuff, like matching non-trivial regexes, doing IO with IO layers, index into Unicode strings and so on.

      You make it sound like "syntactic sugar" is an insult, which it isn't. I wasn't going Luddite, I was merely pointing out that "Modern Perl" comes with a price tag; it can be quite hefty for some applications and may be worth additional consideration.

      You're arguing the software developer side of equation, and of quite advanced hacker, too. I agree that new features can make a developer more productive, but what I'm saying is that it's not given. How many people out there are using this interesting stuff in their day-to-day work? I don't, so I can't run a performance comparison for it. I ran tests for what I do use, and it shows me that even with the latest Perl release my DBD::SQLite application shows 17% performance hit compared to 5.8.9. Does that matter? For me, it does a lot.

      As for your examples, I don't see anything ground-shaking there. Module installer was there for ages, CPAN.pm is working fine for me thanks. Support I have never needed, and if I need security I will buy commercial support anyway. Lots of bug fixes were supposedly backported to 5.8.9 which was released after 5.10 - and how many of later fixes are for later bugs? Unicode is one major advantage, sure, but I don't need it, usually - and considering tchrist's latest musings on stackoverflow, I'd screw it up anyway. So, do I really gain something visible with Modern Perl? Yeah, performance hit. All new features are potential good, but slower execution is here for every existing script and module, every time I run them. Are you ready to dismiss this easily in favor of newer features? I don't.

      In short, I don't think that "Modern Perl is better for everyone" is true.

      That said, I do wish for a magical combination of Modern Perl features and Legacy Perl speed...

      Regards,
      Alex.

        More recent Unicode support int perl-5.14.x is for me the reason to have it already support. I can now do things that I was unable to to till now and also was unable to patch in previous versions.

        I fully agree that the "upgrade" is no upgrade to every single user, but with the current policy of more frequent releases, the number of fixes that are accepted to previous releases has considerably dropped. The chance on an update for 5.8.9 is close to zero, and I also would not wait for an update on 5.10.1. If such an update would be released at all, my bet would be that the only updates would involve being able to build on modern C compilers and maybe a fix for a CVE if such is available. No doc fixes, not added features.

        There have been a huge number of bug-fixes and improvements in the regular expression engine. If your script does not use regular expressions, you won't ever see that. What I like in "Modern Perl" is that regular expressions now offer me more and more a way to express my mind in that expression. The new \K and (?|) might be small changes, but they both simplify my code and make it easier to proceed. Also note that with these constructs, you need less "other" statements in your code to do what you want. The performance gain might thus not be in the expression itself, as well as in the not needing other statements after the regex.

        Also note that modern builds might take some options for the most recent C compilers to take advantage of newer optimization levels. Even if the language itself might have suffered a slowdown in your favorite syntax, the binary might still be faster.

        Also you should consider the more recent architecture. If you are moving from a 32bit OS to a 64bit OS, it might not (only) be the language that shows the slowdown. The interaction with memory management or maybe even emulation layers might have a huge impact on performance.

        If performance is really critical, try to build the versions you are comparing from scratch. Both on the same machine and both with the same build/configure options and then compare again. You might be surprised (or you might not, YMMV).

        As a last note, you are testing with DBD::SQLite. Did you check if the slowdown is in one of the involved modules? DBI, DBD::SQLite also evolve over time, and the modules that are released on CPAN quite often not only fix bugs, but also try to take care of acting as desired for different versions of perl. When comparing, please use the same version of all modules that are used. (when possible)

        As you saw in a previous post from me, I have an external disk with about 85 versions of perl. They are all built under the same conditions with the same configuration (where possible: threads vs non-threads is of course a big deal). This way, I can prove to myself that there is a reproducible performance difference between versions. And then still, I can only prove it for that architecture. IA64 != x86_64.


        Enjoy, Have FUN! H.Merijn
Re: Why "Modern Perl" is slower than "Legacy Perl"?
by Tux (Canon) on Jun 19, 2011 at 15:57 UTC

    I personally don't think that /^$/ is more perlish than eq "" is. Neither is a different layout or the use of single quotes versus the use of double quotes or the use of statement modifiers (action if expression) is better or more modern than (expression and action).

    Modern perl offers more optimizer paths internally, and that is needed because there are so many ways to address a problem. The best way is the way than gets the job done in a manner that the whole team agrees with and is done in a way that the maintainer 5 years from now can still read. Squeezing out nanoseconds on statements that are only visited once in the lifecycle of a program is useless. If the statement however is visited millions of times it might be worthwhile to bench the effect. And the still, it might be only a vilid optimization on that local machine with that build of perl on that architecture.

    I did try your test on the 85 perl builds I have available (all build with the same configuration) and I just noted that threaded perls all came in much slower than unthreaded perls.

    rank elapsed cuser csys pass perl perl + rank ==== ========== ======= ======= ==== ================= ============== +=== ==== 1 0.00363 0.000 0.010 FAIL base/perl5.00504 /pro/bin/perl + 19 2 0.00912 0.000 0.000 FAIL base/perl5.00307 /usr/bin/perl + 34 3 0.02307 0.000 0.000 FAIL base/perl5.00503 base/perl5.003 +07 2 4 0.07953 0.000 0.010 FAIL base/perl5.00405 base/perl5.004 +05 4 5 2.61894 2.580 0.010 PASS base/perl5.6.2 base/perl5.005 +03 3 6 2.68016 2.630 0.020 PASS base/perl5.6.1 base/perl5.005 +04 1 7 2.68523 2.660 0.010 PASS base/perl5.6.0 base/perl5.6.0 + 7 8 2.83037 2.800 0.010 PASS base/perl5.8.0 base/perl5.6.1 + 6 9 2.88885 2.720 0.010 PASS base/perl5.8.3 base/tperl5.6. +1 12 10 2.91004 2.720 0.010 PASS base/perl5.8.2 base/perl5.6.2 + 5 11 2.91830 2.750 0.010 PASS base/perl5.8.7 base/tperl5.6. +2 18 12 2.92083 2.900 0.020 PASS base/tperl5.6.1 base/perl5.8.0 + 8 13 2.92413 2.750 0.010 PASS base/perl5.8.8 base/tperl5.8. +0 20 14 2.93176 2.720 0.010 PASS base/perl5.8.5 base/perl5.8.1 + 15 15 2.93800 2.730 0.020 PASS base/perl5.8.1 base/tperl5.8. +1 23 16 2.94319 2.740 0.010 PASS base/perl5.8.4 base/perl5.8.2 + 10 17 2.94600 2.690 0.010 PASS base/perl5.8.6 base/tperl5.8. +2 24 18 3.00963 2.990 0.010 PASS base/tperl5.6.2 base/perl5.8.3 + 9 19 3.06281 3.020 0.020 PASS /pro/bin/perl base/tperl5.8. +3 25 20 3.09148 3.070 0.020 PASS base/tperl5.8.0 base/perl5.8.4 + 16 21 3.10270 2.860 0.040 PASS base/perl5.8.9 base/tperl5.8. +4 27 22 3.17054 3.000 0.020 PASS base/tperl5.8.7 base/perl5.8.5 + 14 23 3.18847 3.010 0.010 PASS base/tperl5.8.1 base/tperl5.8. +5 28 24 3.20540 3.030 0.020 PASS base/tperl5.8.2 base/perl5.8.6 + 17 25 3.24457 3.070 0.000 PASS base/tperl5.8.3 base/tperl5.8. +6 30 26 3.29392 3.110 0.010 PASS base/tperl5.8.8 base/perl5.8.7 + 11 27 3.29553 3.080 0.010 PASS base/tperl5.8.4 base/tperl5.8. +7 22 28 3.30491 3.010 0.010 PASS base/tperl5.8.5 base/perl5.8.8 + 13 29 3.31124 3.030 0.070 PASS base/perl5.10.1 base/tperl5.8. +8 26 30 3.32899 3.090 0.010 PASS base/tperl5.8.6 base/perl5.8.9 + 21 31 3.43455 3.160 0.040 PASS base/perl5.10.0 base/tperl5.8. +9 46 32 3.43906 3.120 0.070 PASS base/perl5.12.0 base/perl5.10. +0 31 33 3.44477 3.110 0.060 PASS base/perl5.13.4 base/tperl5.10 +.0 55 34 3.52390 3.390 0.000 PASS /usr/bin/perl base/perl5.10. +1 29 35 3.52483 3.210 0.020 PASS base/perl5.13.8 base/tperl5.10 +.1 60 36 3.52753 3.250 0.030 PASS base/perl5.13.6 base/perl5.11. +0 52 37 3.54057 3.250 0.010 PASS base/perl5.13.5 base/tperl5.11 +.0 62 38 3.55223 3.320 0.010 PASS base/perl5.14.0 base/perl5.11. +1 56 39 3.55414 3.200 0.080 PASS base/perl5.11.2 base/tperl5.11 +.1 72 40 3.55444 3.120 0.070 PASS base/perl5.13.2 base/perl5.11. +2 39 41 3.57146 3.150 0.070 PASS base/perl5.13.1 base/tperl5.11 +.2 71 42 3.57274 3.260 0.100 PASS base/perl5.14.1 base/perl5.11. +3 51 43 3.59174 3.310 0.060 PASS base/perl5.13.11 base/tperl5.11 +.3 75 44 3.59178 3.200 0.090 PASS base/perl5.12.4 base/perl5.11. +4 45 45 3.59741 3.160 0.060 PASS base/perl5.11.4 base/tperl5.11 +.4 79 46 3.61302 3.240 0.060 PASS base/tperl5.8.9 base/perl5.11. +5 50 47 3.61401 3.300 0.010 PASS base/perl5.12.3 base/tperl5.11 +.5 64 48 3.63592 3.330 0.080 PASS base/perl5.13.10 base/perl5.12. +0 32 49 3.64948 3.290 0.010 PASS base/perl5.12.1 base/tperl5.12 +.0 73 50 3.65347 3.240 0.070 PASS base/perl5.11.5 base/perl5.12. +1 49 51 3.65606 3.220 0.070 PASS base/perl5.11.3 base/tperl5.12 +.1 65 52 3.69079 3.250 0.080 PASS base/perl5.11.0 base/perl5.12. +2 58 53 3.69301 3.260 0.070 PASS base/perl5.13.3 base/tperl5.12 +.2 84 54 3.71434 3.320 0.080 PASS base/perl5.13.9 base/perl5.12. +3 47 55 3.72287 3.460 0.070 PASS base/tperl5.10.0 base/tperl5.12 +.3 82 56 3.72652 3.270 0.090 PASS base/perl5.11.1 base/perl5.12. +4 44 57 3.73024 3.330 0.050 PASS base/perl5.13.7 base/tperl5.12 +.4 85 58 3.75741 3.280 0.090 PASS base/perl5.12.2 base/perl5.13. +0 59 59 3.77567 3.390 0.060 PASS base/perl5.13.0 base/tperl5.13 +.0 77 60 3.88845 3.640 0.000 PASS base/tperl5.10.1 base/perl5.13. +1 41 61 3.95350 3.700 0.050 PASS base/tperl5.13.10 base/tperl5.13 +.1 66 62 3.99173 3.630 0.060 PASS base/tperl5.11.0 base/perl5.13. +2 40 63 3.99887 3.720 0.080 PASS base/tperl5.14.0 base/tperl5.13 +.2 78 64 3.99972 3.690 0.070 PASS base/tperl5.11.5 base/perl5.13. +3 53 65 4.00705 3.730 0.010 PASS base/tperl5.12.1 base/tperl5.13 +.3 80 66 4.02853 3.710 0.080 PASS base/tperl5.13.1 base/perl5.13. +4 33 67 4.04036 3.740 0.020 PASS base/tperl5.13.6 base/tperl5.13 +.4 83 68 4.04658 3.740 0.020 PASS base/tperl5.13.5 base/perl5.13. +5 37 69 4.06868 3.820 0.010 PASS base/tperl5.13.9 base/tperl5.13 +.5 68 70 4.07103 3.870 0.040 PASS base/tperl5.13.11 base/perl5.13. +6 36 71 4.07516 3.700 0.100 PASS base/tperl5.11.2 base/tperl5.13 +.6 67 72 4.09376 3.760 0.060 PASS base/tperl5.11.1 base/perl5.13. +7 57 73 4.11930 3.790 0.030 PASS base/tperl5.12.0 base/tperl5.13 +.7 81 74 4.11944 3.870 0.010 PASS base/tperl5.14.1 base/perl5.13. +8 35 75 4.13039 3.800 0.050 PASS base/tperl5.11.3 base/tperl5.13 +.8 76 76 4.13756 3.750 0.060 PASS base/tperl5.13.8 base/perl5.13. +9 54 77 4.14126 3.860 0.030 PASS base/tperl5.13.0 base/tperl5.13 +.9 69 78 4.14612 3.740 0.070 PASS base/tperl5.13.2 base/perl5.13. +10 48 79 4.16076 3.830 0.080 PASS base/tperl5.11.4 base/tperl5.13 +.10 61 80 4.17469 3.690 0.080 PASS base/tperl5.13.3 base/perl5.13. +11 43 81 4.17835 3.720 0.120 PASS base/tperl5.13.7 base/tperl5.13 +.11 70 82 4.20535 3.820 0.090 PASS base/tperl5.12.3 base/perl5.14. +0 38 83 4.21454 3.880 0.080 PASS base/tperl5.13.4 base/tperl5.14 +.0 63 84 4.21915 3.780 0.100 PASS base/tperl5.12.2 base/perl5.14. +1 42 85 4.23053 3.860 0.010 PASS base/tperl5.12.4 base/tperl5.14 +.1 74

    Another point in your post includes the work against databases. In my experience, the database is always slower than your perl script, so the gain of a few microseconds in using a syntax that you like/dislike is lost against milliseconds you loose with every database access.


    Enjoy, Have FUN! H.Merijn
      Thanks for suggestions. My benchmarks shown here were rather synthetic; they were for illustrative purposes mostly. I don't usually try to optimize my scripts to the ground, but this case is very special for me. I won't go into detail but I really need to shave off all unnecessary code to save CPU cycles. For me, CPU utilization has always meant code speed and so I was trying to make my code faster so it could run cleaner with regards to CPU. I'm not fanatic about it and I won't rewrite it in C, that would give marginal results vs huge overhead; I consider it an exercise I can afford spending my time at while I'm waiting for the next project phase to begin. Besides, it looked like a perfect opportunity to acquaint myself with Devel::NYTProf, finally. :)

      I must tell that it was very educational for me this way; not only I learnt that newer Perl doesn't mean faster Perl - as your table would suggest, it's actually vice versa - but also I was never aware that speed and CPU utilization are not directly related. In fact, I have discovered it just now and I'm still trying to find an explanation to the fact that the same script ran with Perl 5.6.1 consumes ~4% CPU, but it goes up to ~6% with Perl 5.8.9 and even higher to ~8% with 5.14.1, as reported by prstat. But the test results suggest that it's faster with 8.9! Frankly, I'm at loss - the only explanation I can think up is that Perl 5.6.1 shipped with Solaris has some magic optimizations built in vs vanilla Perl. perl -V does state that it has 48 patches applied, but that doesn't explain the same 2% 5.14 adds over to 5.8. I need to dig up Solaris 10 DVD, set up another virtual machine and try it there - Sol10 ships with Perl 5.8 as standard. But it's black magic anyway.

      Regarding the database optimization, I fully agree with you. If it was any other database engine I would spend my time juggling SQL statements; in case of SQLite it's not so advanced and doesn't have a lot of options to play with. But it's not the case either because the problem was not in SQLite code itself which is highly optimized and blazingly fast, the problem was (and is) in DBD::SQLite that somehow runs twice slower when you use execute_array instead of execute. I tried to check if it was Perl issue instead, and discovered that not all Camels are created equal... It led me to this meditation.

      Regards,
      Alex.

      I just noted that threaded perls all came in much slower than unthreaded perls.
      You sound surprised. I'd gather from your years on p5p that you would know.

      For the rest of the world, it's a known fact that a perl build with thread support is significantly slower than a perl build without thread support (the ability to do threads is already enough for the slowdown - it's a price you pay regardless whether you actually use threads or not). This is why Perl by default (that is, after a ./Configure -d) is build without thread support.

        I'm not surprised that threaded perl builds are slower. I know. I also know that the impact is much less now in more recent perl builds that it was in older perl versions. I can see on a day-to-day basis what the impact is of threads vs non-threads in my smoke status. Today it shows threaded is 5.3% slower than non-threaded. Look at the bottom.

        I hereby would put the word "significantly" into a bit of a context. I still think that 5.3% is significant enough to not want a threaded perl build, as I NEVER ever saw the need for threads.

        With more and more (useful) perl applications actually using threads (e.g. Padre won't even run without them), I can see people wanting them. For me any app requiring threads is reason enough to not even try it.


        Enjoy, Have FUN! H.Merijn
Re: Why "Modern Perl" is slower than "Legacy Perl"?
by flexvault (Monsignor) on Jun 30, 2011 at 13:32 UTC

    Originally when I wrote perl (perl5.4.4 on the IBM RS/6000 AIX Unix) code in the '90s, my interest in perl was to prototype the application and then rewrite it in C. If you look at your sample, you are doing the same! As I have discovered, perl is more than C. Today, I don't use perl to prototype, but use it to develop full projects in less time and with more functionality. ( and usually much faster both in my time and in CPU cycles ).

    Until 2002-3, I never used a hash (and your sample doesn't either). My last large project used 20,000+ lines of actually code plus comments, and maintained sub-second response time consistently with as many as 400 users logged into the system. (Note: I can't image how long it would have taken to do that project in C. ) The code is full of hashes that improve performance.
    Let perl do the look up!

    In the '80s I wrote a wordprocessor to emulate WordPerfect for law office professionals. It was written in C, and as each new operating system/hardware computer emerged, I would rewrite it to get it to work. After a while it was getting less and less portable. Finally, I bit the bullet, and rewrote it in perl. It took about 6 months and I learned about functionality in perl that I had been missing. To my amazement it was faster than the C version. Certain text features were faster in perl than in C. If I had to edit a 8_000_000 line log file, I didn't have to consider the software/hardware architecture, just let perl handle it. By moving from perl5.6.1 to perl5.8.8, it was faster again. So far the fasted perl I have used is 5.12.2, but that is because I'm writing code in perl and not C-like.

    Since you are in a learning and/or relearning cycle with perl, look into the full perl solution, not what was available with perl5.6.1, but what perlish solutions are better today. I'm confident that you'll like and respect the "modern perl".

    Thank you

    "Well done is better than well said." - Benjamin Franklin

      One of the best replies I've read in weeks! I wish I could up this more than once.

      I fully recognize your path. I also worked with (even older) perl on AIX, and when I had to, I always wanted I could do it faster (any other system gave me more vivid response). But I must say that newer AIX also gave newer perl a better architecture to work on. I still hate AIX, but I must say that I hate AIX 5.3 a lot less than I hat AIX 3.1 but I still prefer Linux or HP-UX over AIX in any case.

      And I never ever even consider using C over perl to gain performance. If I have to micro-optimize heavily visited perl code that actually warrants C, I'll write it in XS. That is a proven path (see e.g. the speed comparison between Text::CSV_XS versus Text::CSV_PP), but it has the huge advantage of easy integration into the whole of the perl script.

      Also note that if you have to access databases in C, none of the code is portable between databases. All have their own API and edge cases one has to code around. The low maintenance level of perl scripts using DBI instead is one huge selling point of using perl from the start.


      Enjoy, Have FUN! H.Merijn

        Tux, thank you!

        Background: for AIX, I started with AIX 2.0.x something on the RT. Hopefully, you started with AIX 3.1, since it was much better than the RT version, and like perl, AIX has been getting better. But for programming, I started out writing code in machine language. When I graduated college, my first job was with IBM, and we could write code in assembler. I was in love with computers!

        I like Linux, but it reminds me now of the early days of Unix; every version wants to be different. Thank goodness for perl! I just finished a project yesterday, so I'll be around the Monastery a little more.

        Again, thank you...Ed

        "Well done is better than well said." - Benjamin Franklin

Re: Why "Modern Perl" is slower than "Legacy Perl"?
by chromatic (Archbishop) on Jun 21, 2011 at 15:21 UTC

    In my own experiences, newer versions of Perl 5 use less memory than older versions. That's far more important on some of my projects.

    Memory benchmarks would be very interesting.

Re: Why "Modern Perl" is slower than "Legacy Perl"?
by sundialsvc4 (Abbot) on Jun 21, 2011 at 14:34 UTC

    I could not possibly agree more with Tux: “The best way is the way than gets the job done in a manner that the whole team agrees with and is done in a way that the maintainer 5 years from now can still read.   Squeezing out nanoseconds on statements that are only visited once in the lifecycle of a program is useless.”

    Moore’s Law still applies ... perhaps now more than ever.   But something else is happening, too:   the hardware upon which our applications might be expected to run (or, that they might be expected to serve) is diversifying.   We don’t live in a world of web-browsers anymore.   We don’t “serve web pages.”   We have no way to know which Pad will come out on top, nor what will follow it.

    The “faster” (sic) techniques espoused by older Perls are also older ways, championed at a time when computers (on both the client and the server sides) were much slower and smaller, and the software much less sophisticated.   Software designs today must be, (IMHO) above all other things, “nimble, easily adaptable, and maintainable.”   You need to use the more recently developed techniques.   The “price” that you pay in execution speed is a price that you can well afford to pay.   Attempting to “optimize” it, on the other hand, are a false economy.   I am working long hours right now to try to help rescue a company that stands to lose all of its customers.   (But their program is “fast,” and it runs real good on Netscape 1.0 ...)