-
Notifications
You must be signed in to change notification settings - Fork 284
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
unlock the gvl when calculating hashes / salts #124
Conversation
e02b148
to
c800cf0
Compare
So is this mergeable yet? :) |
I'm going to merge this. I should have merged it a long time ago. 🙇♂️ Bechmarks in 2019: Without this patch:
With this patch:
|
Holding on to the GVL means we can't do anything in parallel. Since these are CPU-only operations that do not involve the ruby interpreter, we can safely unlock the GVL when calculating hashes. This program demonstrates the difference: ```ruby require 'bcrypt' require 'thread' GUESSES = (ENV['GUESSES'] || 100).to_i THREADS = (ENV['THREADS'] || 1).to_i p GUESSES: GUESSES, THREADS: THREADS password = BCrypt::Password.create 'hello world!' queue = Queue.new GUESSES.times { queue << "x" * 90 } THREADS.times { queue << nil } THREADS.times.map { Thread.new { while guess = queue.pop password == guess end } }.each(&:join) ``` Without this patch: ``` [aaron@TC bcrypt-ruby (master)]$ time THREADS=4 ruby test.rb {:GUESSES=>100, :THREADS=>4} real 0m30.014s user 0m29.739s sys 0m0.153s ``` With the patch: ``` [aaron@TC bcrypt-ruby (master)]$ time THREADS=4 ruby -Ilib test.rb {:GUESSES=>100, :THREADS=>4} real 0m12.293s user 0m42.382s sys 0m0.169s ``` If you run this program with the patch, you can see Ruby use nearly 400% CPU, as long as you have a 4 core machine.
The crypt library is almost certainly using `malloc` and not `xmalloc`. We should use `free` instead of `xfree` to ensure the malloc / free calls are correctly balanced.
@tenderlove may be mention this in CHANGELOG? |
Holding on to the GVL means we can't do anything in parallel. Since
these are CPU-only operations that do not involve the ruby interpreter,
we can safely unlock the GVL when calculating hashes.
This program demonstrates the difference:
Without this patch:
With the patch:
If you run this program with the patch, you can see Ruby use nearly 400% CPU,
as long as you have a 4 core machine.
Sending this as a PR because I'm not sure if the feature detection is enough to work on all versions of Ruby we support and I figured I'd let the CI test it. If something fails, I'll add better feature detection.