Optimising Perl with Inline::C
So I got to thinking - in normal every day code, is there any real speed benefit to be had by writing your inner loops in C.
I found an old web page by Mitchell Charity discussing Inline and, interpreting his (slightly pathological) example a little, I got a surprising result:
use strict; use warnings; use Inline 'C'; use Benchmark qw(cmpthese); cmpthese( 50, { perl_method => sub { my $object = new Foo; for(my $i=0;$i<1_000_000;$i++) { $object->set_element($i,67); } }, all_in_one_c => sub { my $object = new Foo; set_all_with_c($object); } }); package Foo; sub new { my $self = " " x 1_000_000; return bless \$self, 'Foo' } sub set_element { my($self,$n,$value) = @_; substr($$self,$n,1) = pack("C",$value); } __END__ __C__ #define USING(object) unsigned char *ptr = SvPVX(SvRV(object)) #define SET_ELEMENT(IDX,VAL) ptr[IDX] = VAL void set_all_with_c (SV* object) { USING(object); int i; for(i=0;i<1000000;i++) { SET_ELEMENT(i, 67); } }
s/iter perl_method all_in_one_c
perl_method 4.16 -- -100%
all_in_one_c 8.60e-03 48321% --
ie. the C code was 48321% times as fast.But it's not really comparing apples with apples - the Perl code is doing a method call on each iteration, the C code is operating on the value directly. In addition, the C code (by way of Inline::C's magic) is basically copying the string into a temporary variable, operating directly on that, and copying back - so the dereferencing is not happening on each loop. We can make those changes in Perl too, and see how that compares.
... sub set_all_with_perl { my $tmp_str = ${ $_[0] }; substr($tmp_str, $_, 1) = pack("C",67) for 0..1_000_000; ${ $_[0] } = $tmp_str; } ...
s/iter perl_method all_in_one_perl all_in_one_c perl_method 4.21 -- -62% -100% all_in_one_perl 1.61 161% -- -99% all_in_one_c 8.60e-03 48821% 18626% --So eliminating the method dispatch and dereference in the loop made our Perl code much faster, but the C code is still way faster. Obviously it's a contrived example, and 1 million iterations is one heck of an inner loop, but I am still surprised by how much difference it made.
01:38 AM, 11 Jan 2008 by Mark Aufflick Permalink | Short Link







