module StrokeDB class ::Class # Declare which methods are optimized for particular language. # It is assumed, that optimized method name looks that way: # method_name_(language name) # # If you supply a block of code, it will be executed in a context of a class # each time optimize! is called. # # You may add some exception handling where you call optimize!. # # Example: # # # assume, there're methods find_C and insert_C # declare_optimized_methods(:C, :find, :insert) { require 'bundle' } # def declare_optimized_methods(lang, *meths, &block) meths.flatten! @optimized_methods ||= {} @optimized_methods_init ||= {} @optimized_methods[lang.to_s] = meths @optimized_methods_init[lang.to_s] = block extend ClassOptimization::ClassMethods end # Returns a list of optimized methods for a given language. # If no language given, a Hash is returned where key is a language name. # def optimized_methods(lang = nil) @optimized_methods ||= {} return @optimized_methods unless lang @optimized_methods[lang.to_s] || [] end end module ClassOptimization module ClassMethods # Switches methods into optimized versions as declared in # declare_optimized_methods. # Pure ruby methods become accessible with suffix _PureRuby. # def optimize!(lang) if block = @optimized_methods_init[lang.to_s] self.instance_eval(&block) end optimized_methods(lang).each do |meth| alias_method(:"#{meth}_PureRuby", :"#{meth}") alias_method(:"#{meth}", :"#{meth}_#{lang}") end end # Reverts method optimization done with optimize! # Note: you may call this method only after optimize! was called. # def deoptimize!(lang) optimized_methods(lang).each do |meth| alias_method(:"#{meth}", :"#{meth}_PureRuby") end end # Executes code in a block with optimizations turned on. # This ensures that appropriate deoptimize! method is called. # def optimized_with(lang) optimize!(lang) yield ensure deoptimize!(lang) end # Iterates through all the optimizations. Non-optimized # mode ("pure Ruby") is yielded first. # Useful for testing and benchmarks. # # Example: # # Klass.with_optimizations(:InlineC) do |lang| # puts "Klass#some_method is written in #{lang}" # puts Klass.new.some_method # end # def with_optimizations(*langs) langs.flatten! yield("pure Ruby") langs.each do |lang| optimized_with(lang) do yield(lang) end end self end end end end