• Literally, C fast in many cases • Java applications can be slow • Oh hey, just like Ruby? • The way you write code is more important than the language you use. Friday, September 14, 12
(a map) • Methods retrieved from class + ancestors • Serial or switch indicates staleness • Weak list of child classes • Class mutation cascades down hierarchy Friday, September 14, 12
indicates staleness • Complexities of lookup, etc • Joy of Ruby interfering with Joy of Opto • Modifying constants triggers invalidation Friday, September 14, 12
Object holds array of values • Call site caches offset plus class ID • Same class, no lookup cost • Can be polymorphically chained Friday, September 14, 12
Access getfield setfield getstatic setstatic Array Access *aload *astore b,s,c,i,l,d,f,a Ten (or 16) “data endpoints” All Java code revolves around these endpoints Remaining ops are stack, local vars, flow control allocation, and math/boolean/bit operations Friday, September 14, 12
setfield getstatic setstatic Array Access *aload *astore b,s,c,i,l,d,f,a Stack Local Vars Flow Control Allocation Boolean and Numeric Friday, September 14, 12
setfield getstatic setstatic Array Access *aload *astore b,s,c,i,l,d,f,a Stack Local Vars Flow Control Allocation Boolean and Numeric Friday, September 14, 12
setfield getstatic setstatic Array Access *aload *astore b,s,c,i,l,d,f,a Stack Local Vars Flow Control Allocation Boolean and Numeric Friday, September 14, 12
JVM at first call asks JRuby what to do • JRuby provides function pointers to code • Pointers include guards, invalidation logic • JRuby and JVM cooperate on optimizing Friday, September 14, 12
• No 10k calls, no JIT (generally) • Inlines up to two targets • Optimistic • Early decisions may be wrong • Small code looks drastically different Friday, September 14, 12
match • JVM treats them as though B lived in A • No call overhead • Variables visible across call boundary • More complete view for optimization Friday, September 14, 12
Not really unrelated • Hotspot optimizes early loop first • Later loop is different...calls “foo” • Assumptions change, perf looks different Friday, September 14, 12
+ 42 * w a = [0] * w * h g = d = 0 f = proc do |n| a[c] += 1 o = a.map {|z| " :#"[z, 1] * 2 }.join.scan(/.{#{w * 2}}/) puts "\f" + o.map {|l| l.rstrip }.join("\n") d += 1 - 2 * ((g ^= 1 << n) >> n) c += [1, w, -1, -w][d %= 4] end 1024.times do !!(!!(!!(!!(!!(!!(!!(!!(!!(true... f[0])...f[1])...f[2])... f[3])...f[4])...f[5])... f[6])...f[7])...f[8]) end end Friday, September 14, 12
+ 42 * w a = [0] * w * h g = d = 0 f = proc do |n| a[c] += 1 o = a.map {|z| " :#"[z, 1] * 2 }.join.scan(/.{#{w * 2}}/) puts "\f" + o.map {|l| l.rstrip }.join("\n") d += 1 - 2 * ((g ^= 1 << n) >> n) c += [1, w, -1, -w][d %= 4] end 1024.times do !!(!!(!!(!!(!!(!!(!!(!!(!!(true... f[0])...f[1])...f[2])... f[3])...f[4])...f[5])... f[6])...f[7])...f[8]) end end Friday, September 14, 12
• JVM JIT limits need to be bumped up • Significant gains for some folks • Long warmup times for so much code • Work continues! Friday, September 14, 12
Indy improvements at VM-level • Compiler improvements at Ruby level • If you can’t compete with JVM... • Still FOSS from top to bottom • Don’t be afraid! Friday, September 14, 12