speeding ducks
play

Speeding Ducks Avi Bryant Meta Heckling welcomed. Ruby is slow - PowerPoint PPT Presentation

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; {


  1. Speeding Ducks Avi Bryant

  2. Meta Heckling welcomed.

  3. Ruby is slow “So what?” “Of course!”

  4. So what? “The Ruby language may be slow, but my app runs plenty fast” True.

  5. 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]; }

  6. ary.pop Java /** rb_ary_pop * */ public IRubyObject pop() { modify(); if (getLength() == 0) { return getRuntime().getNil(); } return (IRubyObject) list.remove(getLength() - 1); }

  7. ary.pop Smalltalk

  8. 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 | ...

  9. 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

  10. Of course! “Ruby is inherently slow because it is so dynamic.” False.

  11. Smalltalk-80

  12. Efficient Implentation of the Smalltalk-80 System L. Peter Deutsch Alan M. Schiffman 1984

  13. Deutsch, 1984 - Native Code cache �� def foo (duck) mov ... ���� duck.waddle cmp ... �� end

  14. Deutsch, 1984 - Native Code invalid �� def foo (duck) mov ... ���� duck.quack! cmp ... �� end

  15. 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

  16. Deutsch, 1984 - Inline Caching 0xDECAF �� def foo (duck) push duck ���� duck.quack! jump(0xBEEF) �� end 0xBEEF �� def quack! ... ���� puts “quack” �� end

  17. 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 ...

  18. 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 ...

  19. 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 ...

  20. SOAR: Smalltalk without Bytecodes David Ungar Dain Samples Paul Hilfinger 1986

  21. Self

  22. Customization: Optimizing Compiler Technology for Self David Ungar Craig Chambers 1989

  23. Optimizing Dynamically-Dispatched Calls with Run-Time Type Feedback David Ungar Urs Hölzle 1994

  24. Self - Polymorphic Inline Caches Duck: 42 �� def foo (duck) Goose: 7 ���� duck.waddle Doctor: 1 �� end

  25. Self - Type feedback inlining �� def foo (duck) if duck.class == Duck ���� duck.quack! puts “quack” �� end else ... end �� def quack! puts “quack” �� end

  26. 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

  27. 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

  28. 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

  29. Strongtalk Ungar, Hölzle, Lars Bak, et al

  30. HotSpot

  31. JavaScript

Recommend


More recommend