Inspired by profiler.rb, I whipped this up to help me with my optimization.
I thought that others could benefit from it. It prints out to STDERR at the 
end of the program an annotated listing, with % of time per line, total CPU 
time per line, and count per line.
Like profiler.rb, it runs quite slowly. However, you can interrupt it with 
the ctrl-C key (at least under Unix).
--------- cut here -------------
module LineProfiler__
  lastNow = Start = Time.times[0]
  lastFile = '(toplevel)'
  lastLine = 0
  lastTimes = [0.0]
  lastCounts = [0]
  Files = {}
 
  p = proc { |event, file, line, id, binding, klass|
  if event == 'line'
    now = Time.times[0] 
    lastTimes[ lastLine ] += now - lastNow
    lastCounts[ lastLine ] += 1
    if lastFile != file
      (lastTimes, lastCounts) = Files.fetch(file) { |name|
        Files[name] = [ Array.new(10000, 0.0), Array.new(10000, 0) ]
      }
      lastFile = file
    end
    lastLine = line
    lastNow = Time.times[0]
  end
  }

  END {
    set_trace_func nil
    total = Time.times[0] - Start
  total /= 100.0  # convert to percent
    f = STDERR
  for file in Files.keys.sort
    f.printf("=========== %s\n", file)
    f.printf(" Line time%%  time  count\n", file)
    lines = IO.readlines(file)
    (times, counts) = Files[file]
    lines.each_index do |line|
      if counts[line+1] > 0
        f.printf("%5d %3.0f%% %6.2f %6d %s",
        line+1, times[line+1]/total, times[line+1], counts[line+1], 
lines[line])
      else
        f.printf("%5d                    %s", line+1, lines[line])
      end
    end
  end
    f.close
  }

  set_trace_func p
end

-- 
Ned Konz
currently: Stanwood, WA
email:     ned / bike-nomad.com
homepage:  http://bike-nomad.com