I used the testcase posted by Wayne and I see that invokedynamic does
speed things up a bit for his testcase.
I ran an experiment to see what happened if the same code was changed to
use globals. I observed the following :
a) With or without invokedynamic, code operating on locals is
significantly faster than code operating on globals
b) While there is improvement, with invokedynamic, for code with locals;
code with globals becomes very slow(or hangs?) with invokedynamic.
What is the reason for a) and b) ?
The following code snippets and results should be self explanatory
==============================with locals==============================
[Karthik:~/test/jruby]cat loop_locals.rb
require ‘benchmark’
def twoArg(a,b)
a + b
end
limit = 0
sum = 0
i = 0
10.times {
puts Benchmark.measure {
i = 0
limit = 10000000
while i < limit
sum = sum + twoArg(5,6)
i = i + 1
end
}
}
puts(“done. loop count: #{limit} checksum: #{sum}”)
[Karthik:~/test/jruby]time jruby -Xcompile.invokedynamic=false
loop_locals.rb
0.960000 0.050000 1.010000 ( 0.636000)
0.420000 0.010000 0.430000 ( 0.387000)
0.410000 0.000000 0.410000 ( 0.405000)
0.410000 0.000000 0.410000 ( 0.404000)
0.410000 0.000000 0.410000 ( 0.409000)
0.400000 0.000000 0.400000 ( 0.401000)
0.400000 0.010000 0.410000 ( 0.405000)
0.410000 0.000000 0.410000 ( 0.403000)
0.420000 0.000000 0.420000 ( 0.410000)
0.400000 0.010000 0.410000 ( 0.410000)
done. loop count: 10000000 checksum: 1100000000
real 0m6.214s
user 0m7.891s
sys 0m0.247s
[Karthik:~/test/jruby]time jruby -Xcompile.invokedynamic=true
loop_locals.rb
0.760000 0.050000 0.810000 ( 0.531000)
0.320000 0.010000 0.330000 ( 0.291000)
0.310000 0.000000 0.310000 ( 0.303000)
0.310000 0.000000 0.310000 ( 0.309000)
0.350000 0.000000 0.350000 ( 0.347000)
0.400000 0.000000 0.400000 ( 0.393000)
0.370000 0.010000 0.380000 ( 0.369000)
0.370000 0.000000 0.370000 ( 0.368000)
0.410000 0.000000 0.410000 ( 0.414000)
0.390000 0.000000 0.390000 ( 0.388000)
done. loop count: 10000000 checksum: 1100000000
real 0m5.667s
user 0m7.420s
sys 0m0.251s
============================with
globals===================================
[Karthik:~/test/jruby]cat loop_globals.rb
require ‘benchmark’
def twoArg(a,b)
a + b
end
$limit = 0
$sum = 0
$i = 0
10.times {
puts Benchmark.measure {
$i = 0
$limit = 10000000
while $i < $limit
$sum = $sum + twoArg(5,6)
$i = $i + 1
end
}
}
puts(“done. loop count: #{$limit} checksum: #{$sum}”)
[Karthik:~/test/jruby]time jruby -Xcompile.invokedynamic=false
loop_globals.rb
2.550000 0.070000 2.620000 ( 2.210000)
2.020000 0.010000 2.030000 ( 1.978000)
1.990000 0.000000 1.990000 ( 1.989000)
2.000000 0.010000 2.010000 ( 1.991000)
2.070000 0.010000 2.080000 ( 2.062000)
2.040000 0.000000 2.040000 ( 2.023000)
2.020000 0.010000 2.030000 ( 2.011000)
2.020000 0.000000 2.020000 ( 2.007000)
2.310000 0.010000 2.320000 ( 2.313000)
2.340000 0.010000 2.350000 ( 2.330000)
done. loop count: 10000000 checksum: 1100000000
real 0m22.756s
user 0m24.597s
sys 0m0.296s
[Karthik:~/test/jruby]time jruby -Xcompile.invokedynamic=true
loop_globals.rb
^C
real 2m4.312s
user 2m26.083s
sys 0m0.851s
[Karthik:~/test/jruby]
[[ Killed the last test run. It does not complete even a single
iteration in 6x the time that the previous(without invokedynamic) run
finished 10 iterations ]]