Skip to content

Instantly share code, notes, and snippets.

@aero
Last active December 14, 2015 07:59
Show Gist options
  • Save aero/5054130 to your computer and use it in GitHub Desktop.
Save aero/5054130 to your computer and use it in GitHub Desktop.
Pure Perl vs Inline::C, simple function and complex function
#!/usr/bin/env perl
use 5.010;
use strict;
use warnings;
use Benchmark;
use Data::Dumper;
timethese(1000000, {
perl => sub { sub_perl(100) },
c => sub { sub_c(100) },
});
my @a = (1..500);
my @b = (501..1000);
#say Dumper( sub_perl_array(scalar @a, @a, @b) );
#say Dumper( sub_c_array(scalar @a, @a, @b) );
timethese(1000, {
perl_array => sub { sub_perl_array(scalar @a, @a, @b) },
c_array => sub { sub_c_array(scalar @a, @a, @b) },
});
sub sub_perl {
return $_[0]+1;
}
sub sub_perl_array {
my ($n) = @_;
my @ret;
foreach (1..$n) {
push @ret, ( $_[$_] * $_[$_+$n] );
}
return \@ret;
}
use Inline C => <<'END_C';
int sub_c (int i) {
return i+1;
}
AV * sub_c_array(SV * x, ...) {
Inline_Stack_Vars;
long array_size, i;
AV * ret = newAV();
array_size = SvUV(Inline_Stack_Item(0));
/* check that array_size matches our expectations,
based on the total number of arguments supplied */
if(Inline_Stack_Items != (2 * array_size) + 1)
croak("Mismatch in number of arguments supplied to foo()");
/* for efficiency, make the array big enough in one fell swoop */
av_extend(ret, array_size - 1);
/* multiply corresponding array elements and push the result into ret +*/
for(i = 1; i <= array_size; i++)
av_push(ret, newSVnv(SvNV(Inline_Stack_Item(i)) *
SvNV(Inline_Stack_Item(i + array_size))));
return ret;
}
END_C
__END__
<result>
Intel(R) Core(TM)2 Quad CPU Q9400 @ 2.66GHz:
Microsoft Windows 7 Enterprise K
Benchmark: timing 1000000 iterations of c, perl...
c: 1 wallclock secs ( 0.23 usr + 0.00 sys = 0.23 CPU) @ 4273504.27/s (n=1000000)
(warning: too few iterations for a reliable count)
perl: 0 wallclock secs ( 0.25 usr + 0.00 sys = 0.25 CPU) @ 4000000.00/s (n=1000000)
(warning: too few iterations for a reliable count)
Benchmark: timing 1000 iterations of c_array, perl_array...
c_array: 0 wallclock secs ( 0.06 usr + 0.00 sys = 0.06 CPU) @ 16129.03/s (n=1000)
(warning: too few iterations for a reliable count)
perl_array: 1 wallclock secs ( 0.17 usr + 0.00 sys = 0.17 CPU) @ 5847.95/s (n=1000)
(warning: too few iterations for a reliable count)
@aero
Copy link
Author

aero commented Feb 28, 2013

Intel(R) Xeon(R) CPU           X5450  @ 3.00GHz
Linux  2.6.18-348.1.1.el5xen #1 SMP Tue Jan 22 17:00:37 EST 2013 x86_64 x86_64 x86_64 GNU/Linux

         c:  0 wallclock secs ( 0.09 usr +  0.00 sys =  0.09 CPU) @ 11111111.11/s (n=1000000)
            (warning: too few iterations for a reliable count)
      perl:  1 wallclock secs ( 0.22 usr +  0.00 sys =  0.22 CPU) @ 4545454.55/s (n=1000000)
            (warning: too few iterations for a reliable count)
Benchmark: timing 1000 iterations of c_array, perl_array...
   c_array:  0 wallclock secs ( 0.04 usr +  0.00 sys =  0.04 CPU) @ 25000.00/s (n=1000)
            (warning: too few iterations for a reliable count)
perl_array:  0 wallclock secs ( 0.14 usr +  0.00 sys =  0.14 CPU) @ 7142.86/s (n=1000)
            (warning: too few iterations for a reliable count)

@yongbin
Copy link

yongbin commented Feb 28, 2013

diff --git a/Inline_bench.pl b/Inline_bench.pl
index 02e3329..e592cff 100644
--- a/Inline_bench.pl
+++ b/Inline_bench.pl
@@ -2,10 +2,10 @@
 use 5.010;
 use strict;
 use warnings;
-use Benchmark;
+use Benchmark qw/cmpthese/;
 use Data::Dumper;

-timethese(1000000, {
+cmpthese(10000000, {
         perl       => sub { sub_perl(100) },
         c          => sub { sub_c(100) },
 });
@@ -16,7 +16,7 @@ my @b = (501..1000);
 #say Dumper( sub_perl_array(scalar @a, @a, @b) );
 #say Dumper( sub_c_array(scalar @a, @a, @b) );

-timethese(1000, {
+cmpthese(10000, {
         perl_array => sub { sub_perl_array(scalar @a, @a, @b) },
         c_array    => sub { sub_c_array(scalar @a, @a, @b) },
 });

@yongbin
Copy link

yongbin commented Feb 28, 2013


.
├── Inline_bench.pl
└── _Inline
    ├── build
    ├── config-darwin-thread-multi-2level-5.014001
    └── lib
        └── auto
            └── Inline_bench_flymake_pl_aceb
                ├── Inline_bench_flymake_pl_aceb.bs
                ├── Inline_bench_flymake_pl_aceb.bundle
                └── Inline_bench_flymake_pl_aceb.inl

find _Inline/ | xargs file
_Inline/:                                                                           directory
_Inline//build:                                                                     directory
_Inline//config-darwin-thread-multi-2level-5.014001:                                ASCII text
_Inline//lib:                                                                       directory
_Inline//lib/auto:                                                                  directory
_Inline//lib/auto/Inline_bench_flymake_pl_aceb:                                     directory
_Inline//lib/auto/Inline_bench_flymake_pl_aceb/Inline_bench_flymake_pl_aceb.bs:     empty
_Inline//lib/auto/Inline_bench_flymake_pl_aceb/Inline_bench_flymake_pl_aceb.bundle: Mach-O 64-bit bundle x86_64
_Inline//lib/auto/Inline_bench_flymake_pl_aceb/Inline_bench_flymake_pl_aceb.inl:    ASCII text

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment