Speeding Ducks Avi Bryant
Meta Heckling welcomed.
Ruby is slow “So what?” “Of course!”
So what? “The Ruby language may be slow, but my app runs plenty fast” True.
Ruby ary.pop C VALUE rb_ary_pop(ary) VALUE ary; { rb_ary_modify_check(ary); if (RARRAY(ary)->len == 0) return Qnil; if (!FL_TEST(ary, ELTS_SHARED) && � RARRAY(ary)->len * 2 < RARRAY(ary)->aux.capa && � RARRAY(ary)->aux.capa > ARY_DEFAULT_SIZE) { � RARRAY(ary)->aux.capa = RARRAY(ary)->len * 2; � REALLOC_N(RARRAY(ary)->ptr, VALUE, RARRAY(ary)->aux.capa); } return RARRAY(ary)->ptr[--RARRAY(ary)->len]; }
ary.pop Java /** rb_ary_pop * */ public IRubyObject pop() { modify(); if (getLength() == 0) { return getRuntime().getNil(); } return (IRubyObject) list.remove(getLength() - 1); }
ary.pop Smalltalk
Ruby �� def pop () ���� return nil if empty? � ���� @total -= 1 ���� index = @start + @total � ���� elem = @tuple . at(index) ���� @tuple . put(index, nil ) � ���� reallocate_shrink() � ���� elem �� end C | Java | Smalltalk | ...
VALUE rb_ary_pop(ary) VALUE ary; { rb_ary_modify_check(ary); if (RARRAY(ary)->len == 0) return Qnil; if (!FL_TEST(ary, ELTS_SHARED) && � RARRAY(ary)->len * 2 < RARRAY(ary)->aux.capa && � RARRAY(ary)->aux.capa > ARY_DEFAULT_SIZE) { � RARRAY(ary)->aux.capa = RARRAY(ary)->len * 2; � REALLOC_N(RARRAY(ary)->ptr, VALUE, RARRAY(ary)->aux.capa); } return RARRAY(ary)->ptr[--RARRAY(ary)->len]; } vs �� def pop () ���� return nil if empty? � ���� @total -= 1 ���� index = @start + @total � ���� elem = @tuple . at(index) ���� @tuple . put(index, nil ) � ���� reallocate_shrink() � ���� elem �� end
Of course! “Ruby is inherently slow because it is so dynamic.” False.
Smalltalk-80
Efficient Implentation of the Smalltalk-80 System L. Peter Deutsch Alan M. Schiffman 1984
Deutsch, 1984 - Native Code cache �� def foo (duck) mov ... ���� duck.waddle cmp ... �� end
Deutsch, 1984 - Native Code invalid �� def foo (duck) mov ... ���� duck.quack! cmp ... �� end
Deutsch, 1984 - Inline Caching 0xDECAF address = lookup(duck, :quack!) �� def foo (duck) push duck ���� duck.quack! jump(address) �� end 0xBEEF �� def quack! ... ���� puts “quack” �� end
Deutsch, 1984 - Inline Caching 0xDECAF �� def foo (duck) push duck ���� duck.quack! jump(0xBEEF) �� end 0xBEEF �� def quack! ... ���� puts “quack” �� end
Deutsch, 1984 - Inline Caching 0xDECAF �� def foo (duck) push duck ���� duck.quack! jump(0xBEEF) �� end 0xBEEF unless self.class == Duck �� def quack! jump(lookup(self.class, :quack!) ���� puts “quack” end �� end ...
Deutsch, 1984 - Inline Caching 0xDECAF �� def foo (duck) push duck ���� duck.quack! jump(0xBEEF) �� end 0xBEEF unless self.class == Duck �� def quack! jump(lookup(self.class, :quack!) � play “q.wav” end �� end ...
Deutsch, 1984 - Inline Caching 0xDECAF address = �� def foo (duck) push duck duck.vtable[3] ���� duck.quack! jump(0xBEEF) jump address �� end 0xBEEF unless self.class == Duck �� def quack! jump(lookup(self.class, :quack!) ���� puts “quack” end �� end ...
SOAR: Smalltalk without Bytecodes David Ungar Dain Samples Paul Hilfinger 1986
Self
Customization: Optimizing Compiler Technology for Self David Ungar Craig Chambers 1989
Optimizing Dynamically-Dispatched Calls with Run-Time Type Feedback David Ungar Urs Hölzle 1994
Self - Polymorphic Inline Caches Duck: 42 �� def foo (duck) Goose: 7 ���� duck.waddle Doctor: 1 �� end
Self - Type feedback inlining �� def foo (duck) if duck.class == Duck ���� duck.quack! puts “quack” �� end else ... end �� def quack! puts “quack” �� end
Self - Type feedback inlining �� def foo (range) ���� range.collect{|x| x * 2} �� end �� def foo (range) result = [] ���� range.each do |x| result.push(x * 2) end result �� end
Self - Type feedback inlining �� def foo (range) ���� range.collect{|x| x * 2} �� end �� def foo (range) result = [] i = range.first while(i <= range.last) result.push(i * 2) i += 1 end result �� end
Self - Type feedback inlining �� def foo (range) ���� range.collect{|x| x * 2} �� end �� def foo (range) result = [] i = range.first while(i <= range.last) result.push(i << 1) i = i + 1 end result �� end
Strongtalk Ungar, Hölzle, Lars Bak, et al
HotSpot
JavaScript
Recommend
More recommend