Description
The #post
method in Executor has a very large amount of overhead:
- Several closures, including one created solely to pass args through to the given block.
- Use of java_method on every call.
- Creation of
[Runnable.java_class]
array on every call.
The closures are especially heavy because they force us to run this method with a heap-based local variable scope, even though it's only used for passing args to task.
I have a few small patches that improve this situation. They're not suitable for a PR at the moment (quick one-off work) but they're there.
https://gist.github.com/headius/3807e0180e83ed7c98a2
This patch does the following:
- Uses a Runnable-implementing Job class to hold args + block, rather than creating another closure.
- Decorates the executors as they're created to have a submit_runnable method that always uses submit(Runnable).
I tested this with both SingleThreadExecutor and ThreadPoolExecutor using the following code (just timing total run time and no warmup):
exe = Concurrent::ThreadPoolExecutor.new
t = Time.now
i = 0
while i < 1_000_000
exe.post { }
i+=1
end
puts Time.now - t
With my changes the run time goes from 29s to around 5s.
I can help you massage these into place, but the patch as written is just a one-off.