-
-
Save headius/3563069 to your computer and use it in GitHub Desktop.
ONE = 1 | |
TWO = 2 | |
def plus(a, b) | |
a + b | |
end | |
def minus(a, b) | |
a - b | |
end | |
def lt(a, b) | |
a < b | |
end | |
def fib_ruby(n) | |
if n < 2 | |
n | |
else | |
fib_ruby(n - 2) + fib_ruby(n - 1) | |
end | |
end | |
def fib_ruby1(n) | |
a = 1 | |
b = 2 | |
if n < b | |
n | |
else | |
fib_ruby(n - b) + fib_ruby(n - a) | |
end | |
end | |
def fib_ruby2(n) | |
if n < TWO | |
n | |
else | |
plus(fib_ruby2(n - TWO), fib_ruby2(n - ONE)) | |
end | |
end | |
def fib_ruby3(n) | |
if lt(n, 2) | |
n | |
else | |
plus(fib_ruby3(minus(n, 2)), fib_ruby3(minus(n, 1))) | |
end | |
end | |
def fib_ruby4(n) | |
if lt(n, TWO) | |
n | |
else | |
plus(fib_ruby4(minus(n, TWO)), fib_ruby4(minus(n, ONE))) | |
end | |
end | |
puts "normal fib" | |
t = Time.now | |
fib_ruby(37) | |
puts Time.now - t | |
t = Time.now | |
fib_ruby(37) | |
puts Time.now - t | |
t = Time.now | |
fib_ruby(37) | |
puts Time.now - t | |
t = Time.now | |
fib_ruby(37) | |
puts Time.now - t | |
t = Time.now | |
fib_ruby(37) | |
puts Time.now - t | |
puts "fib with variables" | |
t = Time.now | |
fib_ruby1(37) | |
puts Time.now - t | |
t = Time.now | |
fib_ruby1(37) | |
puts Time.now - t | |
t = Time.now | |
fib_ruby1(37) | |
puts Time.now - t | |
t = Time.now | |
fib_ruby1(37) | |
puts Time.now - t | |
t = Time.now | |
fib_ruby1(37) | |
puts Time.now - t | |
puts "fib with constants" | |
t = Time.now | |
fib_ruby2(37) | |
puts Time.now - t | |
t = Time.now | |
fib_ruby2(37) | |
puts Time.now - t | |
t = Time.now | |
fib_ruby2(37) | |
puts Time.now - t | |
t = Time.now | |
fib_ruby2(37) | |
puts Time.now - t | |
t = Time.now | |
fib_ruby2(37) | |
puts Time.now - t | |
puts "fib with additional calls" | |
t = Time.now | |
fib_ruby3(37) | |
puts Time.now - t | |
t = Time.now | |
fib_ruby3(37) | |
puts Time.now - t | |
t = Time.now | |
fib_ruby3(37) | |
puts Time.now - t | |
t = Time.now | |
fib_ruby3(37) | |
puts Time.now - t | |
t = Time.now | |
fib_ruby3(37) | |
puts Time.now - t | |
puts "fib with constants and additional calls" | |
t = Time.now | |
fib_ruby4(37) | |
puts Time.now - t | |
t = Time.now | |
fib_ruby4(37) | |
puts Time.now - t | |
t = Time.now | |
fib_ruby4(37) | |
puts Time.now - t | |
t = Time.now | |
fib_ruby4(37) | |
puts Time.now - t | |
t = Time.now | |
fib_ruby4(37) | |
puts Time.now - t |
# JRuby + IR + invokedynamic, Java 7 | |
system ~/projects/jruby $ jruby -Xcompile.invokedynamic=true -X+CIR bench_fib_complex.rb | |
normal fib | |
1.352 | |
1.182 | |
1.178 | |
1.189 | |
1.196 | |
fib with variables | |
1.208 | |
1.185 | |
1.18 | |
1.193 | |
1.195 | |
fib with constants | |
1.268 | |
1.208 | |
1.218 | |
1.2 | |
1.206 | |
fib with additional calls | |
1.445 | |
1.369 | |
1.385 | |
1.382 | |
1.388 | |
fib with constants and additional calls | |
1.448 | |
1.38 | |
1.38 | |
1.396 | |
1.372 | |
# JRUBY normal compiler, no invokedynamic, Java 7 | |
system ~/projects/jruby $ jruby bench_fib_complex.rb | |
normal fib | |
1.677 | |
1.437 | |
1.54 | |
1.442 | |
1.449 | |
fib with variables | |
1.429 | |
1.419 | |
1.413 | |
1.428 | |
1.455 | |
fib with constants | |
4.345 | |
3.48 | |
3.44 | |
3.478 | |
3.46 | |
fib with additional calls | |
4.115 | |
4.019 | |
4.013 | |
3.961 | |
3.947 | |
fib with constants and additional calls | |
5.08 | |
5.037 | |
5.069 | |
5.03 | |
5.038 | |
# JRuby normal compiler, with invokedynamic, Java 7 | |
system ~/projects/jruby $ jruby -Xcompile.invokedynamic=true bench_fib_complex.rb | |
normal fib | |
1.022 | |
0.895 | |
0.882 | |
0.891 | |
0.878 | |
fib with variables | |
0.898 | |
0.903 | |
0.894 | |
0.891 | |
0.878 | |
fib with constants | |
2.294 | |
2.218 | |
2.2 | |
2.219 | |
2.229 | |
fib with additional calls | |
1.263 | |
1.192 | |
1.203 | |
1.191 | |
1.194 | |
fib with constants and additional calls | |
2.498 | |
2.49 | |
2.463 | |
2.464 | |
2.467 | |
# JRuby + IR + indy on Java 8 current preview | |
system ~/projects/jruby $ jruby -Xcompile.invokedynamic=true -X+CIR bench_fib_complex.rb | |
normal fib | |
2.123 | |
1.883 | |
1.906 | |
1.927 | |
1.936 | |
fib with variables | |
1.964 | |
1.949 | |
2.056 | |
1.972 | |
1.95 | |
fib with constants | |
2.537 | |
2.341 | |
2.314 | |
2.321 | |
2.314 | |
fib with additional calls | |
3.023 | |
2.853 | |
2.817 | |
2.784 | |
2.779 | |
fib with constants and additional calls | |
3.814 | |
3.504 | |
3.453 | |
3.464 | |
3.477 | |
# JRuby normal compiler + invokedynamic Java 8 | |
system ~/projects/jruby $ jruby -Xcompile.invokedynamic=true bench_fib_complex.rb | |
normal fib | |
1.273 | |
1.145 | |
1.147 | |
1.142 | |
1.146 | |
fib with variables | |
1.145 | |
1.158 | |
1.146 | |
1.151 | |
1.132 | |
fib with constants | |
4.179 | |
3.973 | |
4.021 | |
3.995 | |
3.993 | |
fib with additional calls | |
5.947 | |
5.105 | |
5.143 | |
5.131 | |
5.112 | |
fib with constants and additional calls | |
3.3 | |
3.275 | |
3.235 | |
3.23 | |
3.21 | |
# Mac Ruby 0.11 | |
system ~/projects/jruby $ macruby bench_fib_complex.rb | |
normal fib | |
1.540885 | |
1.52045 | |
1.514113 | |
1.523034 | |
1.515216 | |
fib with variables | |
1.519008 | |
1.510532 | |
1.522152 | |
1.523368 | |
1.52119 | |
fib with constants | |
4.034211 | |
4.015224 | |
4.041765 | |
4.035574 | |
4.022384 | |
fib with additional calls | |
11.902849 | |
11.898826 | |
11.903194 | |
11.916912 | |
11.928757 | |
fib with constants and additional calls | |
12.526754 | |
12.481892 | |
12.630251 | |
12.696828 | |
12.565837 | |
# Ruby 1.9.3 | |
system ~/projects/jruby $ ruby-1.9.3 bench_fib_complex.rb | |
normal fib | |
8.425049 | |
8.435634 | |
8.470232 | |
8.530792 | |
8.431036 | |
fib with variables | |
8.489791 | |
8.357061 | |
8.407082 | |
8.319713 | |
8.304296 | |
fib with constants | |
12.058306 | |
12.082609 | |
12.078435 | |
12.2678 | |
12.033094 | |
fib with additional calls | |
25.732491 | |
25.687056 | |
25.916108 | |
26.020998 | |
26.290875 | |
fib with constants and additional calls | |
26.128745 | |
26.178898 | |
25.856474 | |
26.035318 | |
25.864822 | |
# Rubinius master | |
system ~/projects/jruby $ ../rubinius/bin/rbx bench_fib_complex.rb | |
normal fib | |
5.78509 | |
5.733961 | |
5.769155 | |
5.753868 | |
5.718023 | |
fib with variables | |
5.718492 | |
5.750543 | |
5.746102 | |
5.761694 | |
5.780769 | |
fib with constants | |
9.956583 | |
9.985609 | |
9.913486 | |
9.954977 | |
9.98208 | |
fib with additional calls | |
15.448432 | |
15.729208 | |
16.458048 | |
15.623091 | |
15.592828 | |
fib with constants and additional calls | |
16.651151 | |
16.625031 | |
16.628007 | |
16.62336 | |
16.639159 | |
# MagLev 1.0.0 | |
system ~/projects/jruby $ rvm maglev do ruby bench_fib_complex.rb | |
normal fib | |
1.79315 | |
1.782173 | |
1.78689 | |
1.797193 | |
1.818359 | |
fib with variables | |
1.829706 | |
1.821148 | |
1.828031 | |
1.82781 | |
1.813357 | |
fib with constants | |
6.875184 | |
6.840194 | |
6.839581 | |
6.848165 | |
6.837607 | |
fib with additional calls | |
3.338842 | |
3.357359 | |
3.34526 | |
3.38869 | |
3.365903 | |
fib with constants and additional calls | |
8.911834000000001 | |
8.871909 | |
8.893435999999999 | |
8.797692 | |
8.829554999999999 |
What is the main difference in generated bytecode between the IR and normal compiler? Why is IR slower in the simpler case, while being faster for the more complex ones?
@thedarkone For the simple cases, the normal compiler wins because it has fast-path logic for numeric operations with literal fixnums, avoiding type and overflow checks in most cases that IR still does. IR is using opaque object references, so it needs to use the normal logic that typechecks and overflow checks.
For the more complex cases, IR compiler wins because it has been designed to pass in everything needed for constant lookup, where the normal compiler pushes that data onto a per-thread stack. That stack juggling ends up opaque to the JVM, so it constant lookup can't be completely optimized away like it can for the IR compiler.
Both compilers can be adapted to do the optimizations the other does, but it will be easier going forward to focus on the IR compile since it is already very functional and far, far simpler than the old compiler.
JRuby and MacRuby being awesome.