Issue #6615 has been updated by drbrain (Eric Hodel).


=begin
Here is a second benchmark using a gzipped file of 1GB from /dev/random, but only for a single thread using

  ruby 2.0.0dev (2012-06-26 trunk 36225) [x86_64-darwin11.4.0]

Code:

  require 'zlib'
  require 'benchmark'
  
  gz = File.read '1G.gz'
  
  z = Zlib::Inflate.new Zlib::MAX_WBITS + 32 # automatic gzip detection
  
  times = Benchmark.measure do
    z.inflate gz
    z.finish
  end
  
  puts times

Without patch:

  $ ruby20 test.rb
    1.850000   0.950000   2.800000 (  2.802966)
  [ 13:55 drbrain@YPCMC10014:~/Work/svn/ruby/trunk ]
  $ ruby20 test.rb
    1.840000   0.950000   2.790000 (  2.791687)
  [ 13:55 drbrain@YPCMC10014:~/Work/svn/ruby/trunk ]
  $ ruby20 test.rb
    1.870000   0.990000   2.860000 (  2.850076)

With patch 3:

  $ make runruby
  ./miniruby -I./lib -I. -I.ext/common  ./tool/runruby.rb --extout=.ext  -- --disable-gems ./test.rb
    1.850000   0.960000   2.810000 (  2.807008)
  $ make runruby
  ./miniruby -I./lib -I. -I.ext/common  ./tool/runruby.rb --extout=.ext  -- --disable-gems ./test.rb
    1.840000   0.930000   2.770000 (  2.771213)
  $ make runruby
  ./miniruby -I./lib -I. -I.ext/common  ./tool/runruby.rb --extout=.ext  -- --disable-gems ./test.rb
    1.840000   0.970000   2.810000 (  2.817809)

So for large files there is no perceptible difference for a single thread.

=end

----------------------------------------
Feature #6615: Release GVL in zlib when calling inflate() or deflate()
https://bugs.ruby-lang.org/issues/6615#change-27497

Author: drbrain (Eric Hodel)
Status: Open
Priority: Normal
Assignee: 
Category: ext
Target version: 2.0.0


This patch switches from zstream_run from using rb_thread_schedule() to rb_thread_blocking_region().

I don't see a way to safely interrupt deflate() or inflate() so the unblocking function is empty.

This patch should allow use of output buffer sizes larger than 16KB.  I suspect 16KB was chosen to allow reasonable context-switching time for ruby 1.8 and earlier.  A larger buffer size would reduce GVL contention when processing large streams.

An alternate way to reduce GVL contention would be to move zstream_run's loop outside the GVL, but some manual allocation would be required as currently the loop uses a ruby String as the output buffer.


-- 
http://bugs.ruby-lang.org/