On Sat, 02 Sep 2006 23:45:17 +0200, Eric Hodel <drbrain / segment7.net> wrote: > On Sep 2, 2006, at 10:42 AM, Dominik Bathon wrote: >> On Sat, 02 Sep 2006 05:26:04 +0200, Eric Hodel <drbrain / segment7.net> >> wrote: >>> I wrote an article on using RubyInline for optimization where I take >>> png.rb, sprinkle in a little profiling and a little C and make it go >>> over 100 times faster. >> >> Nice article, but in this case it is possible to get almost the same >> speedup in pure Ruby: >> >> $ time ruby -Ilib profile.rb >> >> real 0m15.504s >> user 0m15.119s >> sys 0m0.309s >> >> >> Avoiding flatten (and using a literal for the signature): >> >> def to_blob >> blob = [] >> blob << "\211PNG\r\n\032\n" # PNG signature >> blob << PNG.chunk('IHDR', >> [ @height, @width, @bits, 6, 0, 0, 0 ].pack >> ("N2C5")) >> # 0 == filter type code "none" >> data = @data.map { |row| "\0" < row.map { |p| p.values.pack("C*") >> }.join } >> blob << PNG.chunk('IDAT', Zlib::Deflate.deflate(data.join, 9)) >> blob << PNG.chunk('IEND', '') >> blob.join >> end > > This change gives a broken PNG. You meant to call #<<, not #<. Oops, of course I meant #<<. I actually had tested that my changes still produce correct results when I did the optimizations originally. Then I recreated them to get the times for each step and made that typo, oh well. Just for reference, the time for the final version with #< changed to #<< on my machine: $ time ruby -Ilib profile.rb real 0m1.901s user 0m1.841s sys 0m0.032s > I see no significant speedup when using #<<. > >> [values array for string changes] > > These are good. > >> Improving PNG::Canvas#initialize: >> >> Use >> >> @data = Array.new(@width) { |x| Array.new(@height, background) } >> >> instead of >> >> @data = Array.new(@width) { |x| Array.new(@height) { background } } >> >> $ time ruby -Ilib profile.rb >> >> real 0m1.941s >> user 0m1.914s >> sys 0m0.014s > > Not really worth optimizing, since the improvement is so small. In the > optimized RubyInline version only 20% of the time is spent here with no > image generation. Adding image generation makes this optimization > insignificant. Yes, it's not much for the total runtime, but it makes this one line about 14 times faster: $ time ruby -e "40.times { Array.new(400) { Array.new(400) { 0 } } }" real 0m2.430s user 0m2.402s sys 0m0.017s $ time ruby -e "40.times { Array.new(400) { Array.new(400, 0) } }" real 0m0.165s user 0m0.147s sys 0m0.016s > Using your changes from the pure-ruby version I went from about 30 > seconds to about 4 seconds, or 7.5 times faster.