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?
In reply to Why "Modern Perl" is slower than "Legacy Perl"? by dwalin
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |