Faster Ruby Mutexes
Since Thread.critical will be going away with Ruby 1.9 (not to mention the
pain it’s been for other Ruby implementors), I decided to remove the main
reason most programs use it: the fact that stdlib’s Mutex is slow.
Most of Mutex’s performance problems come from two sources:
- It involves a lot of Ruby method calls
- It uses a dynamically sized array to maintain its wait list
To that end, I:
- Rewrote
Mutexin pure C (big savings) - Switched to using a double-headed linked list (
O(1)get and put) - Used a per-mutex memory pool for list entries (so malloc overhead doesn’t kill us)
The end result is actually faster than using Thread.critical directly!
Even Mutex#synchronize, with its block call, is faster than the typical:
saved = Thread.critical
Thread.critical = true
begin
# ...
ensure
Thread.critical = saved
end
Here’s a git repository where you can check out my work:
http://moonbase.rydia.net/software/optimized-locking/optimized-locking.git
I’ve also put up a snapshot tarball for the git-disinclined.
I’ll be working on condition variables next. If they also turn out fast, then purging most explicit uses of Thread.critical from stdlib may become a real possibility.