Closed ThomasSevestre closed 7 years ago
This PR optimize nested connection implementation It gives a 10 to 20% optimisation of ConnectionPool.with
# Ruby 2.3 # user system total real # normal 0.660000 0.010000 0.670000 ( 0.696400) # optim 0.550000 0.010000 0.560000 ( 0.571204) # # Ruby 2.4 # user system total real # normal 0.620000 0.010000 0.630000 ( 0.630224) # optim 0.550000 0.000000 0.550000 ( 0.556212) require 'benchmark' require 'connection_pool' class FastConnectionPool < ConnectionPool def initialize(*args) super @key_count= :"#{@key}-count" end def checkout(options = {}) if ::Thread.current[@key] ::Thread.current[@key_count]+= 1 ::Thread.current[@key] else ::Thread.current[@key_count]= 1 ::Thread.current[@key]= @available.pop(options[:timeout] || @timeout) end end def checkin if ::Thread.current[@key] if ::Thread.current[@key_count] == 1 @available.push(::Thread.current[@key]) ::Thread.current[@key]= nil else ::Thread.current[@key_count]-= 1 end else raise ConnectionPool::Error, 'no connections are checked out' end nil end end pool= ConnectionPool.new { 1 } fpool= FastConnectionPool.new { 1 } n = 100000 Benchmark.bm do |x| x.report("normal") { n.times { pool.with{} } } x.report("optim ") { n.times { fpool.with{} } } end
I've tested locally with ruby 2.4.1 and I don't reproduce the problem detected by travis
Looks like the += and -= operators don't need a mutex because the counter is not actually shared data.
+=
-=
This PR optimize nested connection implementation It gives a 10 to 20% optimisation of ConnectionPool.with