I remembered reading a comment Matz made once about the ! methods. It went something like "! methods are destructive and should only be used when performance is needed". I found a benchmark example that show sort vs sort! speeds are depended on the garbage collection[1]. Today I was reading a chunk of ruby-prof code and found the comment.
def calculate_thread_times
@result.threads.each do |thread_id, methods|
top = methods.sort.last
thread_time = 0.01
thread_time = top.total_time if top.total_time > 0
@thread_times[thread_id] = thread_time
end
end
I rewrote the code with a sort! in my head but wonder would it really have any affects on the time? A little context for test. I just used ruby-prof in an around filter in the application.rb file for a rails project. The html file that ruby-prof produces is not small and includes parts of the rails framework, mysql library, and core ruby code.
require "benchmark"
def calculate_thread_times!(result)
thread_times={}
result.threads.each do |thread_id, methods|
methods.sort!
thread_time = methods.last.total_time > 0 ? methods.last.total_time : 0.01
thread_times[thread_id] = thread_time
end
end
def calculate_thread_times(result)
thread_times ={}
result.threads.each do |thread_id, methods|
top = methods.sort.last
thread_time = 0.01
thread_time = top.total_time if top.total_time > 0
thread_times[thread_id] = thread_time
end
end
Benchmark.bm(12) do |test|
test.report("no_bang:") do
lresult = result
calculate_thread_times(lresult)
end
test.report("bang:") do
lresult = result
calculate_thread_times!(lresult)
end
end
Clearly not enough improvement to stop caching thread times but, now the methods are in order. We could stop caching and access the thread time like
@result.threads[thread_id].last
Since the calculate_thread_times is called when you create a new RubyProf::GraphHtmlPrinter you should never need to call sort again. For example in the ERB template. I did find that using Benchmark.bmbm cause the real values to be swapped just like in the rdoc example[1].
I just submitted a patch to the ruby prof ruby forge group[2]. It is not a big improvement over all. Using my numbers above the current GraphHtmlPrinter use 0.013572 just for sorting. It should now only take 0.004242. Saving the world most a second....
[1] http://www.ruby-doc.org/core/classes/Benchmark.html
[2] http://rubyforge.org/tracker/index.php?func=detail&aid=16364&group_id=1814&atid=7062