Hi.Here comes a patch and two new Java-classes which speeds up Zlib deflate and inflate to more or less C-Ruby-standards. Very nice.
Status for RubyGems right now is that YAML.load(spec) seems to have problems with loading a spec in the size of 3megs. It fizzles for a few hours and then goes OutOfMemoryError.
This is probably the next place for me to start hacking.The speedups in Zlib could probably be done in the GzipReader/GzipWriters too, it's just a matter of time.
Regards Ola Bini
Index: src/lib/ruby/1.8/zlib.rb =================================================================== RCS file: /cvsroot/jruby/jruby/src/lib/ruby/1.8/zlib.rb,v retrieving revision 1.8 diff -u -r1.8 zlib.rb --- src/lib/ruby/1.8/zlib.rb 26 Mar 2006 21:21:40 -0000 1.8 +++ src/lib/ruby/1.8/zlib.rb 6 Apr 2006 16:49:15 -0000 @@ -33,6 +33,8 @@ include_class "java.io.InputStreamReader" include_class "java.io.PipedInputStream" include_class "java.io.PipedOutputStream" +include_class "java.io.StringBufferInputStream" +include_class "java.lang.StringBuffer" include_class "java.util.zip.Deflater" include_class "java.util.zip.DeflaterOutputStream" @@ -45,6 +47,8 @@ include_class "org.jruby.util.CRC32Ext" include_class "org.jruby.util.IOInputStream" include_class "org.jruby.util.IOOutputStream" +include_class "org.jruby.util.ZlibInflate" +include_class "org.jruby.util.ZlibDeflate" # # Implementation of the Zlib library with the help of Java classes @@ -301,32 +305,21 @@ # Decompresses string. Raises a Zlib::NeedDict exception if a preset dictionary is needed for decompression. # def self.inflate(string) - zstream = Zlib::Inflate.new - buf = zstream.inflate(string) - zstream.finish - zstream.close - buf + ZlibInflate.s_inflate(self,string) end # # Creates a new inflate stream for decompression. See zlib.h for details of the argument. If window_bits is nil, the default value is used. # def initialize(window_bits=nil) - if window_bits.nil? - window_bits = Zlib::MAX_WBITS - end - @flater = Inflater.new - @write_stream = PipedOutputStream.new - @intern_stream = PipedInputStream.new(@write_stream) - @stream = InflaterInputStream.new(@intern_stream,@flater) - @val = "" + @infl = ZlibInflate.new(self) end # # Adds p1 to stream and returns self # def <<(p1) - @write_stream.write JString.new(p1.to_s).getBytes("ISO-8859-1") + @infl._append(p1) self end @@ -334,15 +327,14 @@ # No idea, no implementation # def sync_point? - false + @infl.sync_point end # # Sets the preset dictionary and returns string. This method is available just only after a Zlib::NeedDict exception was raised. See zlib.h for details. # def set_dictionary(p1) - @flater.setDictionary(JString.new(p1).getBytes("ISO-8859-1")) - p1 + @infl.set_dictionary(p1) end # @@ -354,23 +346,14 @@ # Set the dictionary by Zlib::Inflate#set_dictionary and then call this method again with an empty string. # def inflate(string) - if string - @write_stream.write JString.new(string).getBytes("ISO-8859-1") - end - while (n = @stream.read) != -1 - @val << n - end - raise Zlib::NeedDict.new if @flater.needsDictionary - val + @infl.inflate(string) end # # This implementation is not correct # def sync(string) - @write_stream.write JString.new(p1).getBytes("ISO-8859-1") - @write_stream.flush - false + @infl.sync(string) end end @@ -686,10 +669,7 @@ # Zlib::BEST_COMPRESSION, Zlib::DEFAULT_COMPRESSION, and an integer from 0 to 9. # def self.deflate(string, level=Zlib::DEFAULT_COMPRESSION) - z = Zlib::Deflate.new(level) - dst = z.deflate(string,Zlib::FINISH) - z.close - dst + ZlibDeflate.s_deflate(self,string,level) end # @@ -709,10 +689,7 @@ if memlevel.nil? memlevel = Zlib::DEF_MEM_LEVEL end - @flater = Deflater.new(level) - @flater.setStrategy(strategy) - @intern_stream = ByteArrayOutputStream.new - @stream = DeflaterOutputStream.new(@intern_stream,@flater) + @defl = ZlibDeflate.new(self,level,window_bits,memlevel,strategy) end # @@ -720,7 +697,7 @@ # Returns self # def <<(p1) - deflate(p1.to_s,Zlib::NO_FLUSH) + @defl._append(p1) self end @@ -728,8 +705,7 @@ # Changes the parameters of the deflate stream. See zlib.h for details. The output from the stream by changing the params is preserved in output buffer. # def params(level,strategy) - @flater.setLevel(level) - @flater.setStrategy(strategy) + @defl.params(level,strategy) end # @@ -737,7 +713,7 @@ # Zlib::ZStream#reset method was called. See zlib.h for details. # def set_dictionary(string) - @flater.setDictionary(JString.new(string).getBytes("ISO-8859-1")) + @defl.set_dictionary(string) end # @@ -745,7 +721,7 @@ # method is just provided to improve the readability of your Ruby program. # def flush(flush=Zlib::SYNC_FLUSH) - deflate('',flush) + @defl.flush(flush) end # @@ -756,21 +732,7 @@ # The value of flush should be either Zlib::NO_FLUSH, Zlib::SYNC_FLUSH, Zlib::FULL_FLUSH, or Zlib::FINISH. See zlib.h for details. # def deflate(string,flush=nil) - if string.nil? - finish - @intern_stream.toByteArray.to_a.pack("C*") - else - @stream.write(JString.new(string).getBytes("ISO-8859-1")) - case flush - when Zlib::FINISH - finish - @intern_stream.toByteArray.to_a.pack("C*") - when Zlib::SYNC_FLUSH - @stream.flush - when Zlib::FULL_FLUSH - @stream.flush - end - end + @defl.deflate(string,flush) end end
ZlibInflate.java
Description: Binary data
ZlibDeflate.java
Description: Binary data