# Adventures in Optimization.. When a Ruby primitive is the Hog

**URL:** <https://www.ruby-forum.com/t/adventures-in-optimization-when-a-ruby-primitive-is-the-hog/154593>\
**Category:** Ruby\
**Created:** [December 2, 2008, 1:10am UTC](https://www.ruby-forum.com/t/adventures-in-optimization-when-a-ruby-primitive-is-the-hog/154593 "2008-12-02T01:10:12Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![amin1426](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/4da419/32.png) [@amin1426](https://www.ruby-forum.com/u/amin1426)\
**Post date:** [December 2, 2008, 1:10am UTC](https://www.ruby-forum.com/t/adventures-in-optimization-when-a-ruby-primitive-is-the-hog/154593/1 "2008-12-02T01:10:12Z")

</div>

So you’ve run your code with -rprofile or require ‘profile’

And the answer was IO.each\_line

Which is a bit like saying the answer to the Question of Life, the  
Universe and Everything is “42”.

a) You’ve used IO.each\_line in many places.  
b) There is nothing you can do to speed it up.

Enter Carter’s Canny Primitive Profiler…

$f=Hash.new(0)

CUNNING\_MIN\_CARE = 1 # Only care about stack frames that have been  
called  
# at least CUNNING\_MIN\_CARE times  
CUNNING\_DEPTH = 2 # Profile base on CUNNING\_DEPTH number of  
# stack frames of this calls that that  
calls… that  
# calls Array.each  
# Make it -1 if you want the lot.

at\_exit{  
$f.keys.find\_all{|k| $f[k] \>= CUNNING\_MIN\_CARE}.sort\_by{|k|  
$f[k]}.each{|k|  
puts “\n\n#{k} \>\>\>#{$f[k]}\<\<\<”  
}  
}

class IO  
alias\_method :orig\_each\_line, :each\_line  
def each\_line(&block)  
i=0  
orig\_each\_line do |l|  
block.call(l)  
i+= 1  
end  
ensure  
$f[caller(1)[0…CUNNING\_DEPTH].join("\n")] += i  
end  
end

On exit you can _see_ which invocation of each\_line via which path was  
the busiest!

Of course, sometimes we don’t actually care about CPU time. The by  
several orders of magnitude, the slowest operation in a modern PC is  
pulling stuff of the disk.

So how about this variation on the Theme…  
class IO  
alias\_method :orig\_read, :read  
def read(\*arg)  
start = Time.now  
orig\_read(\*arg)  
ensure  
$f[caller(1)[0…CUNNING\_DEPTH].join("\n")] += Time.now - start  
end  
end

I love Ruby 🙂

John C. Phone : (64)(3) 358 6639  
Tait Electronics Fax : (64)(3) 359 4632  
PO Box 1645 Christchurch Email : removed\_email\_address@domain.invalid  
New Zealand
