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

speeding ducks
SMART_READER_LITE
LIVE PREVIEW

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


slide-1
SLIDE 1

Speeding Ducks

Avi Bryant

slide-2
SLIDE 2

Meta

Heckling welcomed.

slide-3
SLIDE 3

Ruby is slow

“So what?” “Of course!”

slide-4
SLIDE 4

So what?

“The Ruby language may be slow, but my app runs plenty fast”

True.

slide-5
SLIDE 5

Ruby

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
slide-6
SLIDE 6

Java

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

Smalltalk

ary.pop
slide-8
SLIDE 8

Ruby

C | Java | Smalltalk | ...

def pop() return nil if empty?
  • @total -= 1
index = @start + @total
  • elem = @tuple.at(index)
@tuple.put(index,nil)
  • reallocate_shrink()
  • elem
end
slide-9
SLIDE 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
slide-10
SLIDE 10

Of course!

“Ruby is inherently slow because it is so dynamic.”

False.

slide-11
SLIDE 11
slide-12
SLIDE 12

Smalltalk-80

slide-13
SLIDE 13

Efficient Implentation of the Smalltalk-80 System

  • L. Peter Deutsch

Alan M. Schiffman 1984

slide-14
SLIDE 14

Deutsch, 1984 - Native Code

def foo(duck) duck.waddle end mov ... cmp ...

cache

slide-15
SLIDE 15

Deutsch, 1984 - Native Code

def foo(duck) duck.quack! end mov ... cmp ...

invalid

slide-16
SLIDE 16

Deutsch, 1984 - Inline Caching

def foo(duck) duck.quack! end address = lookup(duck, :quack!) push duck jump(address) def quack! puts “quack” end ...

0xBEEF 0xDECAF

slide-17
SLIDE 17

Deutsch, 1984 - Inline Caching

def foo(duck) duck.quack! end def quack! puts “quack” end ...

0xBEEF 0xDECAF

push duck jump(0xBEEF)

slide-18
SLIDE 18

Deutsch, 1984 - Inline Caching

def foo(duck) duck.quack! end def quack! puts “quack” end

0xBEEF 0xDECAF

push duck jump(0xBEEF) unless self.class == Duck jump(lookup(self.class, :quack!) end ...

slide-19
SLIDE 19

Deutsch, 1984 - Inline Caching

def foo(duck) duck.quack! end def quack! play “q.wav” end

0xBEEF 0xDECAF

push duck jump(0xBEEF) unless self.class == Duck jump(lookup(self.class, :quack!) end ...

slide-20
SLIDE 20

Deutsch, 1984 - Inline Caching

def foo(duck) duck.quack! end def quack! puts “quack” end

0xBEEF 0xDECAF

push duck jump(0xBEEF) unless self.class == Duck jump(lookup(self.class, :quack!) end ... address = duck.vtable[3] jump address

slide-21
SLIDE 21

SOAR: Smalltalk without Bytecodes

David Ungar Dain Samples Paul Hilfinger 1986

slide-22
SLIDE 22

Self

slide-23
SLIDE 23

Customization: Optimizing Compiler Technology for Self

David Ungar Craig Chambers 1989

slide-24
SLIDE 24

Optimizing Dynamically-Dispatched Calls with Run-Time Type Feedback

David Ungar Urs Hölzle 1994

slide-25
SLIDE 25

Self - Polymorphic Inline Caches

def foo(duck) duck.waddle end

Duck: 42 Goose: 7 Doctor: 1

slide-26
SLIDE 26

Self - Type feedback inlining

def foo(duck) duck.quack! end def quack! puts “quack” end if duck.class == Duck puts “quack” else ... end

slide-27
SLIDE 27

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

slide-28
SLIDE 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 * 2) i += 1 end result end

slide-29
SLIDE 29

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

slide-30
SLIDE 30

Strongtalk

Ungar, Hölzle, Lars Bak, et al

slide-31
SLIDE 31

HotSpot

slide-32
SLIDE 32
slide-33
SLIDE 33
slide-34
SLIDE 34

JavaScript