Business Model [[email protected] rails (master)]$ cd ~/git/omglolwut2 [[email protected] omglolwut2]$ cat app/models/business.rb class Business < ApplicationRecord # Business model end [[email protected] omglolwut2]$
Run an empty program [[email protected] ~]$ ruby -v ruby 2.3.0p0 (2015-12-25 revision 53290) [x86_64-darwin15] [[email protected] ~]$ time ruby -e' ' real 0m0.101s user 0m0.061s sys 0m0.032s OMG RUBY IS SLOW
Gem Prelude if defined?(Gem) require 'rubygems.rb' begin require 'did_you_mean' rescue LoadError end if defined?(DidYouMean) end Load Rubygems did_you_mean New in Ruby 2.3!
Did you mean? [[email protected] ~]$ ruby -e'Object.new.object_ip' -e:1:in `': undefined method `object_ip' for #0x007fa7938b4fd8> (NoMethodError) Did you mean? object_id [[email protected] ~]$ I see you’re trying to call a method!
# RubyGems's require: TL;DR alias :original_require :require def require file original_require file rescue LoadError found_gem = all_gems.find do |gem| gem.contains?(file) || gem.contains?(file + ".rb") || gem.contains?(file + ".so") # .bundle on OS X, .dll on Windows end if found_gem found_gem.activate # mutates $LOAD_PATH original_require file else raise "idk lol" end end RubyGems’ Require O(3N) or just O(N)
How does GC impact? require 'benchmark/ips' # GC.disable # Uncomment to measure GC Benchmark.ips do |x| x.report("something") do call_some_method end end
Require Process Start to require 'b' Acquire lock for "b" Start to require 'c' Acquire lock for "c" Try to require 'b' Already locked for "b" Finish require 'c' Finish require 'b' Release lock for "c" Release lock for "b"
Compiled vs Non-Compiled [[email protected] omglolwut (master)]$ time RUBYOPT='-I. -rx' bin/rails db:migrate real 0m1.804s user 0m1.487s sys 0m0.414s [[email protected] omglolwut (master)]$ time COMP=1 RUBYOPT='-I. -rx' bin/rails db:migrate real 0m1.273s user 0m1.002s sys 0m0.374s Before (not compiled) After (compiled)
Future Work Upstream new callback Compile code on `gem install` Cache invalidation If you like "cache invalidation", try "naming things"! Advertisement:
Inline Caching class Hello def bar; end end def foo(object) object.bar end foo Hello.new foo Hello.new `object` is Hello, where is foo? `object` is Hello, I know where foo is. HIT! Cache Contents Key Value [Hello, foo] method source
Inline Caching class Hello def bar; end end class World def bar; end end def foo(object) object.bar end foo Hello.new foo World.new `object` is Hello, where is foo? MISS `object` is World, where is foo? MISS Cache Contents Key Value [Hello, foo] method source
Cache size: 2 class Hello def bar; end end class World def bar; end end def foo(object) object.bar end foo Hello.new foo World.new foo Hello.new foo World.new `object` is Hello, where is foo? MISS `object` is World, where is foo? MISS `object` is Hello, I know foo. HIT `object` is World, I know foo. HIT Cache Contents Key Value [Hello, foo] method source [World, foo] method source
Class Creation Code class Hello end def foo(object) object.bar end 2.times { hello = Hello.new hello.instance_eval do end } Creates a new subclass of Hello Always sees an anonymous class
Benchmark class C1 def m; 1; end end o1 = C1.new o2 = C1.new o2.singleton_class i = 0 while i<6_000_000 # benchmark loop 2 o = (i % 2 == 0) ? o1 : o2 o.m; o.m; o.m; o.m; o.m; o.m; o.m; o.m i += 1 end
Run it! [[email protected] ruby (trunk)]$ time ./ruby benchmark/ bm_vm2_poly_singleton.rb real 0m2.510s user 0m2.453s sys 0m0.024s [[email protected] ruby (singleton-serial)]$ time ./ruby benchmark/ bm_vm2_poly_singleton.rb real 0m1.380s user 0m1.319s sys 0m0.020s