From: "drbrain (Eric Hodel)" Date: 2012-06-27T06:02:42+09:00 Subject: [ruby-core:45897] [ruby-trunk - Feature #6615] Release GVL in zlib when calling inflate() or deflate() 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/