J
Joel VanderWerf
Ruby folks,
The following implementation of Thread.exclusive (called
Thread.my_exclusive) seems to gain a bit on the thread.rb implementation:
user system total real
warmup 0.300000 0.000000 0.300000 ( 0.296724)
exclusive 7.000000 0.000000 7.000000 ( 7.006737)
my_exclusive 5.040000 0.010000 5.050000 ( 5.294778)
exclusive 6.950000 0.000000 6.950000 ( 7.170255)
my_exclusive 4.970000 0.000000 4.970000 ( 4.964166)
(850MHz PIII, linux 2.4.21, ruby 1.9.0)
Can anyone see any reason not to use it? There is slightly different
semantics w.r.t. subclasses of Thread that redefine #critical, but I
think the difference is benign. Also, there is no way that
Thread.critical can raise an exception (in the curreny ruby source), so
that's not going to cause a problem with the placement of the "old =
critical" line.
The main reason I'm interested in this is some heavily threaded code
that spends 20% of process time in Thread.exclusive (according to the
profiler). I can probably improve this by using Thread.critical and
Thread.critical= instead, but why not improve Thread.exclusive itself?
The new implementation (actually I've been using it for a year without
knowing it was different from thread.rb) seems quite stable in my stress
tests.
----
require 'thread'
require 'benchmark'
class Thread
# Slightly faster (30%) replacement for Thread.exclusive.
def self.my_exclusive
old = critical
self.critical = true
yield
ensure
self.critical = old
end
end
# ---- From thread.rb: ----
#
# class Thread
# #
# # FIXME: not documented in Pickaxe or Nutshell.
# #
# def Thread.exclusive
# _old = Thread.critical
# begin
# Thread.critical = true
# return yield
# ensure
# Thread.critical = _old
# end
# end
# end
Benchmark.bm(15) do |bm|
n = 1_000_000
bm.report "warmup" do
n.times do
end
end
bm.report "exclusive" do
n.times do
Thread.exclusive do
end
end
end
bm.report "my_exclusive" do
n.times do
Thread.my_exclusive do
end
end
end
bm.report "exclusive" do
n.times do
Thread.exclusive do
end
end
end
bm.report "my_exclusive" do
n.times do
Thread.my_exclusive do
end
end
end
end
The following implementation of Thread.exclusive (called
Thread.my_exclusive) seems to gain a bit on the thread.rb implementation:
user system total real
warmup 0.300000 0.000000 0.300000 ( 0.296724)
exclusive 7.000000 0.000000 7.000000 ( 7.006737)
my_exclusive 5.040000 0.010000 5.050000 ( 5.294778)
exclusive 6.950000 0.000000 6.950000 ( 7.170255)
my_exclusive 4.970000 0.000000 4.970000 ( 4.964166)
(850MHz PIII, linux 2.4.21, ruby 1.9.0)
Can anyone see any reason not to use it? There is slightly different
semantics w.r.t. subclasses of Thread that redefine #critical, but I
think the difference is benign. Also, there is no way that
Thread.critical can raise an exception (in the curreny ruby source), so
that's not going to cause a problem with the placement of the "old =
critical" line.
The main reason I'm interested in this is some heavily threaded code
that spends 20% of process time in Thread.exclusive (according to the
profiler). I can probably improve this by using Thread.critical and
Thread.critical= instead, but why not improve Thread.exclusive itself?
The new implementation (actually I've been using it for a year without
knowing it was different from thread.rb) seems quite stable in my stress
tests.
----
require 'thread'
require 'benchmark'
class Thread
# Slightly faster (30%) replacement for Thread.exclusive.
def self.my_exclusive
old = critical
self.critical = true
yield
ensure
self.critical = old
end
end
# ---- From thread.rb: ----
#
# class Thread
# #
# # FIXME: not documented in Pickaxe or Nutshell.
# #
# def Thread.exclusive
# _old = Thread.critical
# begin
# Thread.critical = true
# return yield
# ensure
# Thread.critical = _old
# end
# end
# end
Benchmark.bm(15) do |bm|
n = 1_000_000
bm.report "warmup" do
n.times do
end
end
bm.report "exclusive" do
n.times do
Thread.exclusive do
end
end
end
bm.report "my_exclusive" do
n.times do
Thread.my_exclusive do
end
end
end
bm.report "exclusive" do
n.times do
Thread.exclusive do
end
end
end
bm.report "my_exclusive" do
n.times do
Thread.my_exclusive do
end
end
end
end