Two threads connected by a queue, passing one fixnum at a time, doing
trivial calculations. Run time should be linear in number of inputs,
right? Well, yeah, for 1.8.7 and jruby, but not for 1.9.3p0.
Here's the code, with timing outputs in the DATA section:
require 'thread'
N = Integer(ARGV.shift || 1000)
q = Queue.new
th = Thread.new do
n = 0
while x = q.pop
n += 1
end
puts "n = #{n}"
end
time0 = Process.times
N.times do
100.times do |x|
q.push x
end
end
q.push nil
th.join
time1 = Process.times
puts "utime = #{time1.utime - time0.utime}"
__END__
$ ruby -v
ruby 1.9.3p0 (2011-10-30) [x86_64-linux]
$ ruby th.rb 10
n = 1000
utime = 0.01
$ ruby th.rb 100
n = 10000
utime = 0.01
$ ruby th.rb 1000
n = 100000
utime = 0.33999999999999997
$ ruby th.rb 10000
n = 1000000
utime = 44.65
Memory usage is pretty flat--seems to stay under 15MB.
For comparison, here's the same series on ruby 1.8.7:
$ ruby1.8 -v
ruby 1.8.7 (2010-06-23 patchlevel 299) [x86_64-linux]
$ ruby1.8 th.rb 10
n = 1000
utime = 0.01
$ ruby1.8 th.rb 100
n = 10000
utime = 0.14
$ ruby1.8 th.rb 1000
n = 100000
utime = 0.16
$ ruby1.8 th.rb 10000
n = 1000000
utime = 1.43
And FWIW the same series on jruby, but the comparison is probably
muddled by the JIT compiler:
$ jruby -v -e 'p RUBY_VERSION'
jruby 1.6.5 (ruby-1.9.2-p136) (2011-10-25 9dcd388) (Java HotSpot(TM)
64-Bit Server VM 1.6.0_26) [linux-amd64-java]
"1.9.2"
$ jruby th.rb 10
n = 1000
utime = 0.0349998474121094
$ jruby th.rb 100
n = 10000
utime = 0.293999910354614
$ jruby th.rb 1000
n = 100000
utime = 1.52300000190735
$ jruby th.rb 10000
n = 1000000
utime = 2.90700006484985