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


=begin

This benchmarks inflates 100,000 1000byte deflate strings.  1000 bytes is smaller than the default Zlib buffer size, so use of realloc vs REALLOC_N should not matter.

Code:

  require 'zlib'
  require 'benchmark'
  
  r = Random.new 0
  
  file_count = 100_000
  
  deflated = (0..file_count).map do
    input = r.bytes 1000
    Zlib::Deflate.deflate input
  end
  
  times = Benchmark.measure do
    deflated.each do |input|
      Zlib::Inflate.inflate input
    end
  end
  
  puts times

Without patch:

  $ for f in `jot 5`; do ruby20 test.rb; done
    0.810000   0.060000   0.870000 (  0.864994)
    0.800000   0.050000   0.850000 (  0.863737)
    0.800000   0.060000   0.860000 (  0.851056)
    0.830000   0.060000   0.890000 (  0.887332)
    0.810000   0.060000   0.870000 (  0.866989)

With patch:

  $ for f in `jot 5`; do make runruby; done
    0.780000   0.060000   0.840000 (  0.851944)
    0.800000   0.060000   0.860000 (  0.865989)
    0.770000   0.050000   0.820000 (  0.823333)
    0.770000   0.060000   0.830000 (  0.828246)
    0.760000   0.060000   0.820000 (  0.828063)

Slight decrease in time.

=end

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

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/