Upload
littlebigruby
View
555
Download
7
Tags:
Embed Size (px)
Citation preview
COPIOUS FREE TIME
Fedora Packaging
•beanstalkd•haproxy•libtomcrypt•libtommath•nginx•ragel•tinyproxy
Ruby Gems
•keybox•rabal•launchy•heel•htauth•amalgalite•hitimes•stickler•crate
I LOVE RUBY
I LIKE C
ANYEXTENSION DEVELOPERS
IN THE HOUSE ?
WHO HAS USED FFI?
WHO HAS HEARD OF FFI?
WHAT IS FFI?
LIBFFIhttp://sourceware.org/libffi/
“A foreign function interface is the popular name for the interface that allows code written in one language
to call code written in another language.”
libsomething.so
Applicationuses
libsomething_foo()
FFIRuntim
e
libsomething.so
ruby-something C extension
Matz RubyInterpreter
App
JRubyInterpreter
App
RubiniusInterpreter
App
built-in libffi or ffi gem
something-ffi (pure ruby)
1 #ifndef __SIMPLE_METRICS_H__ 2 #define __SIMPLE_METRICS_H__ 3 #include <stdlib.h> 4 #include <math.h> 5 6 typedef struct _simple_metrics{ 7 double min; 8 double max; 9 double sum;10 double sumsq;11 long count;12 } simple_metrics ;13 14 simple_metrics* simple_metrics_new();15 void simple_metrics_free( simple_metrics* sm );16 void simple_metrics_update( simple_metrics* sm, double value );17 double simple_metrics_mean( simple_metrics* sm );18 double simple_metrics_min( simple_metrics* sm );19 double simple_metrics_max( simple_metrics* sm );20 double simple_metrics_sum( simple_metrics* sm );21 long simple_metrics_count( simple_metrics* sm );22 double simple_metrics_stddev( simple_metrics* sm );23 double simple_metrics_rate( simple_metrics* sm );24 25 #endif
1 class Metric 2 attr_reader :name 3 def initialize( name ) 4 @name 5 end 6 7 def update( new_value) ... end 8 def count ... end 9 def max ... end10 def mean ... end11 def min ... end12 def rate ... end13 def sum ... end14 def stddev ... end15 end
142 void Init_simple_metrics_ext()143 {144 VALUE cSM_Common;145 146 mSM = rb_define_module( "SimpleMetrics" );147 mSME = rb_define_module_under( mSM, "Ext" );148 149 /* load the class we inherit from */150 rb_require("simplemetrics/common");151 152 cSM_Common = rb_const_get( mSM, rb_intern( "Common" ) );153 154 cSME_Metric = rb_define_class_under( mSME, "Metric", cSM_Common );155 156 rb_define_alloc_func(cSME_Metric, sm_alloc); 157 rb_define_method( cSME_Metric, "initialize", sm_initialize, 1 );158 rb_define_method( cSME_Metric, "update", sm_update, 1 );159 rb_define_method( cSME_Metric, "count", sm_count, 0 );160 rb_define_method( cSME_Metric, "max", sm_max, 0 );161 rb_define_method( cSME_Metric, "min", sm_min, 0 );162 rb_define_method( cSME_Metric, "mean", sm_mean, 0 );163 rb_define_method( cSME_Metric, "rate", sm_rate, 0 );164 rb_define_method( cSME_Metric, "sum", sm_sum, 0 );165 rb_define_method( cSME_Metric, "stddev", sm_stddev, 0 );166 167 }
7 module SimpleMetrics 8 module FFI 9 10 class Struct < ::FFI::ManagedStruct11 layout :min, :double, :max, :double, :sum, :double, 12 :sumsq, :double, :count, :long13 def self.release( ptr )14 SimpleMetrics::FFI.simple_metrics_free( ptr )15 end16 end17 18 extend ::FFI::Library19 ffi_lib "libsimple_metrics"20 21 attach_function :simple_metrics_new, [ ], :pointer22 attach_function :simple_metrics_free, [ :pointer ], :void23 attach_function :simple_metrics_update,[ :pointer, :double ], :void24 attach_function :simple_metrics_min, [ :pointer ], :double25 attach_function :simple_metrics_max, [ :pointer ], :double26 attach_function :simple_metrics_mean, [ :pointer ], :double27 attach_function :simple_metrics_sum, [ :pointer ], :double28 attach_function :simple_metrics_count, [ :pointer ], :long29 attach_function :simple_metrics_stddev,[ :pointer ], :double30 attach_function :simple_metrics_rate, [ :pointer ], :double31 32 end33 end
library function parameters return type
35 module SimpleMetrics36 module FFI37 class Metric < ::SimpleMetrics::Common38 include ::SimpleMetrics::FFI39 def initialize( name )40 super41 @impl = FFI.simple_metrics_new42 end43 44 def update( v )45 simple_metrics_update( @impl, v )46 end47 48 self.keys.each do |f|49 module_eval <<-code50 def #{f}51 simple_metrics_#{f}( @impl )52 end53 code54 end55 end56 end57 end
10 class Struct < ::FFI::ManagedStruct11 layout :min, :double, 12 :max, :double, 13 :sum, :double, 14 :sumsq, :double, 15 :count, :long16 def self.release( ptr )17 SimpleMetrics::FFI.simple_metrics_free( ptr )18 end19 end
6 typedef struct _simple_metrics{ 7 double min; 8 double max; 9 double sum;10 double sumsq;11 long count;12 } simple_metrics ;
14 simple_metrics* simple_metrics_new();15 void simple_metrics_free( simple_metrics* sm );16 void simple_metrics_update( simple_metrics* sm, double value );17 double simple_metrics_mean( simple_metrics* sm );18 double simple_metrics_min( simple_metrics* sm );19 double simple_metrics_max( simple_metrics* sm );20 double simple_metrics_sum( simple_metrics* sm );21 long simple_metrics_count( simple_metrics* sm );22 double simple_metrics_stddev( simple_metrics* sm );23 double simple_metrics_rate( simple_metrics* sm );
21 extend ::FFI::Library22 ffi_lib "libsimple_metrics"23 24 attach_function :simple_metrics_new, [ ], :pointer25 attach_function :simple_metrics_free, [ :pointer ], :void26 attach_function :simple_metrics_update,[ :pointer, :double ], :void27 attach_function :simple_metrics_mean, [ :pointer ], :double28 attach_function :simple_metrics_min, [ :pointer ], :double29 attach_function :simple_metrics_max, [ :pointer ], :double30 attach_function :simple_metrics_sum, [ :pointer ], :double31 attach_function :simple_metrics_count, [ :pointer ], :long32 attach_function :simple_metrics_stddev,[ :pointer ], :double33 attach_function :simple_metrics_rate, [ :pointer ], :double
FFI Traditional C Extension
Jeremy’s Time
1 Million update() calls
Will it Blend run on JRuby?
40 minutes 70 minutes
1.16 sec 0.42 sec
Yes No
MEANINGLESS METRICS
% ruby ~/Projects/simple_metrics/example/bench.rb 1000000generating 1000000 random numbers between 0 and 10,000Rehearsal -----------------------------------------------ext 0.420000 0.000000 0.420000 ( 0.460806)ffi 1.160000 0.000000 1.160000 ( 1.171498)-------------------------------------- total: 1.580000sec
user system total realext 0.420000 0.010000 0.430000 ( 0.424809)ffi 1.160000 0.000000 1.160000 ( 1.182928)
% ./bin/jruby ~/Projects/simple_metrics/example/bench.rb 1000000generating 1000000 random numbers between 0 and 10,000Skipping ExtRehearsal -----------------------------------------------ffi 0.922000 0.000000 0.922000 ( 0.922000)-------------------------------------- total: 0.922000sec
user system total realffi 0.834000 0.000000 0.834000 ( 0.834000)
FFI GEMS
4ffi-ncurses
ffi-swig-generator ffi-zlib
tidy_ffi
GEMS WITH EXTENSIONS
346Out of 4,501 gems
GETTO
WORK!!
THANKS
• Wayne Meissner - adding libffi to JRuby and providing the ffi gem for MRI.
• Evan Phoenix - using libffi in Rubinius
• Authors of the examples on the Project Kenai wiki
LINKS
• http://blog.headius.com/2008/10/ffi-for-ruby-now-available.html
• http://kenai.com/projects/ruby-ffi
• http://wmeissner.blogspot.com/
• http://www.igvita.com/2009/01/15/bridging-mri-jruby-rubinius-with-ffi/
• http://blog.segment7.net/articles/2008/01/15/rubinius-foreign-function-interface
QUESTIONS?