From: Dominik Bathon Date: 2006-07-17T03:39:28+09:00 Subject: Re: How to speed up ruby and make it as fast as possible On Sun, 16 Jul 2006 09:40:47 +0200, Austin Ziegler wrote: > On 7/14/06, Dominik Bathon wrote: >> Ruby2CExtension doesn't support 100% of Ruby's features, but it supports >> enough to handle real world libraries. It can compile Austin Ziegler's >> PDF::Writer for example (with some small changes). The resulting C >> extension is about 33% faster (i.e. 3s instead of 4s) than the Ruby >> code. > > I'd love to hear what those changes are. Here they are: diff -ruw lib_orig/pdf/writer/fontmetrics.rb lib/pdf/writer/fontmetrics.rb --- lib_orig/pdf/writer/fontmetrics.rb 2005-06-16 06:28:25.000000000 +0200 +++ lib/pdf/writer/fontmetrics.rb 2006-07-08 01:33:40.000000000 +0200 @@ -57,6 +57,7 @@ font = nil afm = nil + resss = nil metrics_path.each do |path| afm_file = File.join(path, "#{name}.afm").gsub(/\.afm\.afm$/o, ".afm") rfm_file = "#{afm_file}.rfm" @@ -67,7 +68,8 @@ if File.exists?(rfm_file) data = File.open(rfm_file, "rb") { |file| file.read } font = Marshal.load(data) - return font + resss = font + break end rescue nil @@ -188,6 +190,7 @@ end rescue nil # Ignore file errors break unless font.nil? end + return resss if resss raise ArgumentError, "Font #{font_name} not found." if font.nil? font This is because return from inside a block is not supported. diff -ruw lib_orig/pdf/writer.rb lib/pdf/writer.rb --- lib_orig/pdf/writer.rb 2005-09-07 19:01:14.000000000 +0200 +++ lib/pdf/writer.rb 2006-07-08 01:34:32.000000000 +0200 @@ -1687,7 +1687,7 @@ tw = width / size.to_f * 1000 pos = -1 - loop do + while true pos += 1 break if pos == text.size font_change = true Again because return from inside a block is not supported (so I just changed the block to a while loop). diff -ruw lib_orig/transaction/simple.rb lib/transaction/simple.rb --- lib_orig/transaction/simple.rb 2005-05-05 18:16:49.000000000 +0200 +++ lib/transaction/simple.rb 2006-07-08 01:33:00.000000000 +0200 @@ -650,7 +650,8 @@ if respond_to?(:instance_variable_get) instance_variable_set(vv, rr.instance_variable_get(vv)) else - instance_eval(%q|#{vv} = rr.instance_eval("#{vv}")|) + $__________xxxxxxxx___rr = rr + instance_eval(%q|#{vv} = $__________xxxxxxxx___rr.instance_eval("#{vv}")|) end end This is because the instance_eval wouldn't see the local variable rr. That's all that I changed to get it to compile and the resulting C extension seems to work correctly with the demos. Dominik