From: Sam Roberts Date: 2006-05-23T04:49:04+09:00 Subject: Re: Zed and Luis drop the bomb on Ruby's poor performance Quoting james_b@neurogami.com, on Tue, May 23, 2006 at 01:50:34AM +0900: > Those people having speed issues: Is it not a reasonable option to > replace the bottleneck Ruby code with custom compiled C libraries? Its not obvious that this can always help, though it might in some cases. I've been benchmarking vpim's icalendar decoding, and haven't found any way to get it significantly faster yet. Its a bit of an issue, a utility I use a lot to print out events and todos for the next week usually takes 5-10 seconds to run. This is long enough to notice! When I tried running profile, and it told me 40% of the time was spent in String case-insensitive comparisons, so I reworked the internals to always uppercase strings so that wasn't necessary. Got about 5%. I even tried using symbols instead of strings, I expected from lisp experience that symbol comparisons would be really fast, but they are only slightly faster (for strings of the size I'm working with anyway). ** I ran out of time at that point, but its not clear to me what kind of algorithmic changes I can make to speed things up, and I'm not too sure where the time is being spent, other than in string operations. There definitely isn't one part of the app I can point to and say "recode that in C and my problems will go away". Also, you might have noticed but ruby libraries that require extensions to be compiled tend to not get a lot of traction in the ruby community. Anyhow, I just spent a weekend on performance tuning, I might still find out some clever way to restructure my code so that it gets twice as fast, but a 2-3 times speed improvement would make a big difference to my library. The difference between 6 seconds and under 2 seconds is huge in human interface terms. Cheers, Sam ** user system total real noop 0.700000 0.000000 0.700000 ( 0.698633) String#== 2.410000 0.010000 2.420000 ( 2.445288) String#casecmp 2.650000 0.000000 2.650000 ( 2.652620) Symbol#== 2.280000 0.000000 2.280000 ( 2.274505) String#to_sym 2.460000 0.000000 2.460000 ( 2.449362) String#up 4.730000 0.000000 4.730000 ( 4.721140) String#up#to_sym 6.030000 0.000000 6.030000 ( 5.986897) -- bench.rb -- require 'benchmark' require 'pp' str0 = "a" * 20 str1 = str0.upcase sym0 = str0.to_sym sym1 = str1.to_sym $N = 1000000 Benchmark.bm(20) do |x| x.report("noop") do $N.times do end end x.report("String#==") do $N.times do str0 == str1 end end x.report("String#casecmp") do $N.times do str0.casecmp(str1) end end x.report("Symbol#==") do $N.times do sym0 == sym1 end end x.report("String#to_sym") do $N.times do str1.to_sym end end x.report("String#up") do $N.times do str1.upcase end end x.report("String#up#to_sym") do $N.times do str1.upcase.to_sym end end end