laziness, impatience, and hubris | |
PerlMonks |
#!/usr/bin/perl -w use Inline C; use strict; hello_inline(); __END__ __C__ #include <stdio.h> void hello_inline( ) { printf( "Hello World. Best Regards from Inline\n" ); }
In order to use the rest of the examples, download and install the services library. Make sure you install it in a directory where your compiler/loader can find the header and library. You can still use Inline if the files are in an odd location but you would need to configure your Inline properly.
This next snippet of Inline just exposes that part of the services library that reads the file. (This is also a sub-benefit of Inline, you can pare-down or wrapper only those parts of a library which you deem important).
#!/usr/bin/perl use Inline C => DATA => LIBS => '-lservices'; # Here's how we would configure Inline if our headers and # libraries are in a non-standard location #use Inline C => DATA => # INC => '-I/usr/local/include' => # LIBS => '-L/usr/local/lib -lservices'; my_services(); __END__ __C__ #include <libservices.h> int my_services( ) { struct serv *serv_list = serv_load(NULL); struct serv *serv = serv_list; for (; serv; serv = serv->next) { printf("%s %s %s \n", serv->name, serv->port, serv->proto ); } serv_destroy(serv_list); return 1; }
#!/usr/bin/perl -w use Inline C => DATA => LIBS => '-lservices'; my( @srvs ) = my_services(); foreach( @srvs ) { foreach( @$_ ) { print $_, " "; } print "\n"; } __END__ __C__ #include <libservices.h> void my_services( ) { struct serv *serv_list = serv_load(NULL); struct serv *serv = serv_list; SV *record[3]; AV *entry; Inline_Stack_Vars; Inline_Stack_Reset; for (; serv; serv = serv->next) { record[0] = newSVpv(serv->name, 0 ); record[1] = newSVpv(serv->port, 0 ); record[2] = newSVpv(serv->proto, 0 ); Inline_Stack_Push(newRV_noinc((SV*)av_make(3,record))); } serv_destroy(serv_list); Inline_Stack_Done; }
#!/usr/bin/perl -w use Benchmark; use Inline C => DATA => LIBS => '-lservices'; use strict; timethese( 500, { 'inline' => sub{ &inline(); }, 'pure' => sub{ &pure(); }, } ); sub pure { my( $serv, $pp, $rst, $port, $proto, $array, @all ); open( SERVICES, "</etc/services" ) or die "Cannot open: $!\n"; while( <SERVICES> ) { next if /^#/; next if /^\s+$/; ( $serv, $pp, $rst ) = split( /\s+/, $_ ); ( $port, $proto ) = split( /\//, $pp ); #print $serv, " ", $port, " ", $proto, " ", "\n"; push( @all, [$serv,$port,$proto] ); } close( SERVICES ); @all; } sub inline { my( @srvs ) = my_services(); } __END__ __C__ #include <libservices.h> void my_services( ) { struct serv *serv_list = serv_load(NULL); struct serv *serv = serv_list; SV *record[3]; AV *entry; Inline_Stack_Vars; Inline_Stack_Reset; for (; serv; serv = serv->next) { record[0] = newSVpv(serv->name, 0 ); record[1] = newSVpv(serv->port, 0 ); record[2] = newSVpv(serv->proto, 0 ); Inline_Stack_Push(newRV_noinc((SV*)av_make(3,record))); } serv_destroy(serv_list); Inline_Stack_Done; }
Benchmark: timing 500 iterations of inline, pure... inline: 3 wallclock secs ( 2.67 usr + 0.38 sys = 3.05 CPU) @ 16 +3.93/s (n=500) pure: 8 wallclock secs ( 8.65 usr + 0.16 sys = 8.81 CPU) @ 56 +.75/s (n=500) Benchmark: timing 500 iterations of inline, pure... inline: 3 wallclock secs ( 2.58 usr + 0.46 sys = 3.04 CPU) @ 16 +4.47/s (n=500) pure: 9 wallclock secs ( 8.64 usr + 0.11 sys = 8.75 CPU) @ 57 +.14/s (n=500) Benchmark: timing 500 iterations of inline, pure... inline: 3 wallclock secs ( 2.63 usr + 0.41 sys = 3.04 CPU) @ 16 +4.47/s (n=500) pure: 8 wallclock secs ( 8.62 usr + 0.15 sys = 8.77 CPU) @ 57 +.01/s (n=500)
-derby
updated: return type for hello_inline function was incorrect (thanks ariels). Also just recently read tye remarks about posting snippets to pm should cannocalize the shebang to /usr/bin/perl (I just wish I could find that node again - no luck with search or supersearch).
|
---|