redis-rb icon indicating copy to clipboard operation
redis-rb copied to clipboard

String#slice! instead of buffered IO in Redis::Connection::SocketMixin#read and #gets

Open apetrov opened this issue 9 years ago • 1 comments

Redis::Connection::SocketMixin#read Redis::Connection::SocketMixin#gets abuse String#slice! and should use StringIO as better alternative of buffered read in terms of both CPU and memory. Quick test reveal a shortcoming of the existing solution:

require 'benchmark'
require 'stringio'
buffer1 = "f"*2048
buffer2 = StringIO.new(buffer1.clone)
Benchmark.bm do |x|
  x.report do  # for the sake of the test we should measure how long does it take to clone buffer
    1000_000.times do 
      buffer1.clone
    end
  end
  x.report do
    1000_000.times do 
      # yes, we create a new string
      buffer1.clone.slice!(0,1024)
    end
  end
  x.report do
    1000_000.times do 
      buffer2.read(1024)
      buffer2.rewind
    end
  end
end

output

  0.270000   0.000000   0.270000 (  0.280817)
   1.730000   0.550000   2.280000 (  2.290668)
   0.670000   0.190000   0.860000 (  0.868489)

2.290668 - 0.280817 = 2.009851 (discount allocation of new strings for test purposes) 2.009851 vs 0.868489 is the significant difference.

apetrov avatar Apr 13 '16 10:04 apetrov

Is this why getting the result of an sinter with 500k items takes 7 seconds without hiredis? I was a little confused, because using Ruby to parse the redis-cli response the naive way ($stdin.read.split("\n")) is quite fast.

nevinera avatar Oct 04 '20 14:10 nevinera

Closing as stale since all this code was just replaced for the upcoming 5.0.

byroot avatar Aug 17 '22 19:08 byroot