Skip to content

Embed URL

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Shows the performance effects of crossing the JRuby <--> Java bridge, and using JRuby's java_method.
# Illustrates the overhead of the JRuby <--> Java bridge
# parameter and return value type conversions, and the
# dramatic performance improvement that can be had by
# specifying the Java overload using java_method.
require 'java'
require 'benchmark'
ITERATION_COUNT = ARGV.empty? ? 100_000 : ARGV.first.to_i
JMath = java.lang.Math
# Test the max strategy, which is passed as a block taking x and y params.
def test
ITERATION_COUNT.times do
x = rand(1_000_000)
y = rand(1_000_000)
max = yield(x, y)
max.class # do something w/max so Java optimizer doesn't eliminate it
end
end
def java_test
test { |x,y| java.lang.Math.max(x, y) }
end
def java_test_with_alias
java_long_max = java.lang.Math.java_method(:max, [Java::long, Java::long])
test { |x,y| java_long_max.(x, y) }
end
def java_test_with_math_alias
test { |x,y| JMath.max(x, y) }
end
def ruby_test_inline
test { |x, y| x >= y ? x : y }
end
def ruby_max(x, y)
x >= y ? x : y
end
def ruby_test_with_function
test { |x, y| ruby_max(x, y) }
end
def main
iteration_count_str = java.text.NumberFormat.instance.format(ITERATION_COUNT)
puts "Performing #{iteration_count_str} iterations for tests.\n"
java_time = Benchmark.measure { java_test }.real
java_alias_time = Benchmark.measure { java_test_with_alias }.real
java_math_alias_time = Benchmark.measure { java_test_with_math_alias }.real
ruby_inline_time = Benchmark.measure { ruby_test_inline }.real
ruby_function_time = Benchmark.measure { ruby_test_with_function }.real
fastest_time = [java_time, java_alias_time, java_math_alias_time, \
ruby_inline_time, ruby_function_time].min
puts '%-24.24s%+16s%+16s%+16s' % ['', 'Total', 'Average', 'X / Min'] # header
puts '%-24.24s%+16s%+16s%+16s' % ['', '(sec)', '(nsec)', '']
output = ->(label, time) do
average_time = 1_000_000_000 * time / ITERATION_COUNT
relative_time = time / fastest_time
puts '%-24.24s%16.4f%16.4f%16.4f' % [label, time, average_time, relative_time]
end
output.('Using Java:', java_time)
output.('Using Java w/alias:', java_alias_time)
output.('Using Java w/math alias:', java_math_alias_time)
output.('Using Ruby inline:', ruby_inline_time)
output.('Using Ruby w/function:', ruby_function_time)
end
main
=begin
On Mac OS, Java version 1.6.0_37:
>ruby max_example.rb 100_000 2> /dev/null
Performing 100,000 iterations for tests.
Total Average X / Min
(sec) (nsec)
Using Java: 1.2030 12029.9983 29.3415
Using Java w/alias: 0.0880 880.0006 2.1463
Using Java w/math alias: 0.0690 690.0001 1.6829
Using Ruby inline: 0.0410 409.9989 1.0000
Using Ruby w/function: 0.0510 510.0012 1.2439
>ruby max_example.rb 2_000_000 2> /dev/null
Performing 2,000,000 iterations for tests.
Total Average X / Min
(sec) (nsec)
Using Java: 6.1250 3062.5000 9.5703
Using Java w/alias: 1.2600 630.0000 1.9687
Using Java w/math alias: 1.3790 689.5001 2.1547
Using Ruby inline: 0.7200 360.0000 1.1250
Using Ruby w/function: 0.6400 320.0001 1.0000
>ruby max_example.rb 100_000_000 2> /dev/null
Performing 100,000,000 iterations for tests.
Total Average X / Min
(sec) (nsec)
Using Java: 123.6610 1236.6100 4.7720
Using Java w/alias: 39.1120 391.1200 1.5093
Using Java w/math alias: 43.0850 430.8500 1.6626
Using Ruby inline: 25.9140 259.1400 1.0000
Using Ruby w/function: 30.5850 305.8500 1.1803
On Linux (Mint, Ubuntu-based, 3.2.0-23-generic),
------------------------------------------------
[0] 12:47 toshiba-mint /home/kbennett/work/jruby-test
>ruby jruby_java_max_benchmark.rb 2> /dev/null
Performing 100,000 iterations for tests.
Total Average X / Min
(sec) (nsec)
Using Java: 0.9680 9679.9994 22.5116
Using Java w/alias: 0.0940 939.9986 2.1860
Using Java w/math alias: 0.0830 829.9994 1.9302
Using Ruby inline: 0.0430 429.9998 1.0000
Using Ruby w/function: 0.0500 500.0019 1.1628
[0] 13:04 toshiba-mint /home/kbennett/work/jruby-test
>ruby jruby_java_max_benchmark.rb 2_000_000 2> /dev/null
Performing 2,000,000 iterations for tests.
Total Average X / Min
(sec) (nsec)
Using Java: 3.0020 1501.0000 5.8863
Using Java w/alias: 0.8300 415.0000 1.6275
Using Java w/math alias: 0.9270 463.5000 1.8176
Using Ruby inline: 0.5100 255.0000 1.0000
Using Ruby w/function: 0.5370 268.5001 1.0529
[0] 13:04 toshiba-mint /home/kbennett/work/jruby-test
>ruby jruby_java_max_benchmark.rb 100_000_000 2> /dev/null
Performing 100,000,000 iterations for tests.
Total Average X / Min
(sec) (nsec)
Using Java: 87.8330 878.3300 3.7964
Using Java w/alias: 36.9640 369.6400 1.5977
Using Java w/math alias: 40.8660 408.6600 1.7663
Using Ruby inline: 23.1360 231.3600 1.0000
Using Ruby w/function: 24.5630 245.6300 1.0617
I use the 2>/dev/null to suppress the output of the ambiguous function
warning, but that's not necessary, and shouldn't be used as is w/Windows.
=end
@rohitn

Doubt it changes the results but line 31 should be test { |x, y| x >= y ? x : y }

@keithrbennett

Thanks for catching that! I've corrected the code.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.