From: Christoph Date: 2002-03-21T13:04:47+09:00 Subject: Some Windows (re | bench)marks (Re: building latest cvs ruby on win) wrote in .... > > Sorry, I've missed ext/configsub.rb and fixed now. Thank you very much for the quick fix ... however there an old build problem (under VS6 and VS7) still remains The culprit is mswin32-ruby17.def (generated by mkexport.rb). The offending lines look like --- .... SafeFree Win32System _real@0000000000000000 _real@3eb0c6f7a0b5ed8d .... _real@bff0000000000000 _real@c1d0000000000000 chown closedir .... ---- Without removing _real@0000000000000000 ... (this must be done during the build process) the build fails with a link error complaining about missing symbols. Additionally it is probably save to remove all non human readable symbols from the export list in mswin32-ruby.def. Besides shrinking mswin*.dll in size it also has a measurable performance effect ( ~ 10-15 % in the test script below). Using a full /Ox optimization (this includes a frame-pointer optimization) removes all of the non-readable symbols from the export list and adds another ~ 10 - 15 % speed improvement in my test script below. Unfortunately running ``nmake test'' (or installing) uncovers a problem with printf - for example --- ruby -e 'printf "bla %d bla %s\n", 2,Object' --- -e:1:in `printf': failed to convert Class into Integer (TypeError) from -e:1 --- Given the not insignificant performance increase it might be a good idea to further investigate this issue. At a first glance I did not find any other problem associated to the usage of a full /Ox optimization - for example ``nmake test'' succeeds after modifying the ``printf'' lines of the ``sample/test.rb'' file in Ruby;s cvs-source tree. The biggest performance booster is a switch of compliers: Using the VS7-C++ compiler over a VS6-C++ compiler results in a executable which is a whopping ~75 % faster (in my test case that is). To put in perspective: A ``VS7-C++ & /Ox'' compiled cvs-Ruby is ~ 10 % faster as an aggressively complied Cygwin cvs-Ruby. ~ 100 % faster as VS6-C++ compiled cvs-Ruby (with stock optimizations) ~ 150 % faster than the current Prag-Prog Ruby /Christoph ---- ## The test script is a modified version of my ``entry'' in the addagram ## contest. I use a ~ 1/4 million wordlist. require 'benchmark' def Benchmark.times Process::times end class Solve Min = 3 Max = 30 def initialize(file) succ = Terminal.new @table = (Min..Max).collect do # @table = Array.new(Max - Min+1) do curr = succ succ = Normal.new curr curr end Benchmark::bm(9) do |x| x.report('build up:') { File.open(file).read.split.each do |wrd| unless (len = wrd.length - Min ) < 0 @table[len].set_wrd(wrd) end end } @solve = nil x.report('solve :') { (Max-Min).downto(0) do |i| break if @solve = @table[i].solve end } end end attr_reader :solve private Terminal = Hash.clone class Terminal tmp =[180643669, 1,13,705643 ,81806611,113,257,569, 37047091,2749, 6089,13441,29683,65537,7597757,319567, 23 ,1558177,3440719, 144719,16777213, 1249, 53, 5, 398893589,880828517] @@weight = Array.new(65).concat(tmp.concat(Array.new(6).concat(tmp))) tmp = instance_methods - Object.instance_methods def __solve(hsh) return [ fetch(hsh) { return nil } ] end def solve length.zero? ? nil : [to_a[0][1]] end def set_wrd(wrd) hsh = 0 wrd.each_byte { |b| hsh+= @@weight[b] } store(hsh,wrd) end def verify(s,t,remove_byte) tmp = t.unpack("c*") tmp.each_index do |i| if i == remove_byte tmp.delete_at(i) return s.unpack("c*").sort.pack("c*") \ == tmp.sort.pack("c*") end end end # removing unnecessary methods has no measurable effect # on performance and is for esthetics only ... tmp -= ["[]","store","fetch","each","to_a","delete"] tmp.each {|m| remove_method m } end class Normal < Terminal def initialize(prev) @prev = prev end def __solve(hsh) wrd = fetch(hsh) {return nil} wrd.each_byte do |b| if res = @prev.__solve(hsh- @@weight[b]) return res.unshift(wrd) if verify(res[0],wrd,b) end end delete(hsh) return nil end def solve each do |hsh,wrd| wrd.each_byte do |b| if res = @prev.__solve(hsh- @@weight[b]) return res.unshift(wrd) if verify(res[0],wrd,b) end end end return nil end end end problem = Solve.new('LongList.txt') puts problem.solve -----