Upgrade to a newer jruby. Release 1.4.0 has been available for months
and 1.5.0-dev is stable.
Use more than 4000 iterations to benchmark anything with jruby. It
gets penalized for taking longer to startup. Also, the JVM needs more
iterations for the really smart optimizations to kick in via HotSpot.
Here is your bench redone.
require ‘benchmark’
def sum_upto_inject(nr)
(1…nr).inject(0) { |sum,n| sum+n }
end
def sum_upto_each(nr)
sum = 0
(1…nr).each { |n| sum += n }
sum
end
def bm
bm = Benchmark.measure do
n = 4000
(1…n).each { |nr| yield(nr) }
end
puts bm
end
bm { |nr| sum_upto_each(nr) }
bm { |nr| sum_upto_inject(nr) }
Also note that we have a faster implementation of inject for actual
Arrays (and we could optimize Range similiarly). Try this version of
sum_upto_inject(nr):
def sum_upto_inject(nr)
(1…nr).to_a.inject(0) { |sum,n| sum+n }
end
You’ll see that inject is much closer to each performance for an Array.
And of course this reports only a single run; if you simply wrap the
two bm calls in “5.times { }” the subsequent iterations are anywhere
from 15-25% faster.
Ultimately, this bench is largely measuring block dispatch performance
more than anything else, and it’s a known issue in JRuby that blocks
receiving 2 or more arguments currently have a lot more overhead than
blocks receiving one argument. So inject here is paying a higher
penalty simply because it takes two arguments. We plan to fix it, but
it hasn’t been a high priority up to now.
Charlie
On Tue, Feb 2, 2010 at 4:47 PM, Thomas E Enebo [email protected]
wrote:
-Tom
require ‘benchmark’
Upgrade to a newer jruby. Release 1.4.0 has been available for months and 1.5.0-dev is stable.
 sum = 0
end
 18.094000  0.000000  18.094000 ( 18.048000)
103.910543 Â 0.000000 103.910543 (103.910585)
  http://xircles.codehaus.org/manage_email