Error in profiler

Hi folks,

I have some code which I wanted to run under the profiler but it's
raising an error within the profiler code:

c:/ruby/lib/ruby/1.8/profiler.rb:27: undefined method `[]' for
nil:NilClass (NoMethodError)
        from c:/ruby/lib/ruby/1.8/profiler.rb:5:in `times'
        from art.rb:119:in `times'
        from art.rb:119

The code is:

    http://matt.blogs.it/gems/art.rb

The profiler generates some output suggesting the error isn't thrown
immediately. However the code runs without any errors outside of the
profiler.

I had a look at profiler.rb but I can't make head nor tail of it.
From the section in PickAxe2 it doesn't suggest you need to modify
your code to make it compatible with the profiler.

Can anyone help me?

Regards,

Matt

p.s. I had *thought* someone recently posted a new, faster, profiler
but I'm starting to doubt my memory since I can't find any trace of it
in my GMail archive, google, or archived issues of Ruby Weekly News.
Did I imagine it?

···

--
Matt Mower :: http://matt.blogs.it/

Hi.

I have some code which I wanted to run under the profiler but it's
raising an error within the profiler code:

c:/ruby/lib/ruby/1.8/profiler.rb:27: undefined method `' for
nil:NilClass (NoMethodError)
       from c:/ruby/lib/ruby/1.8/profiler.rb:5:in `times'
       from art.rb:119:in `times'
       from art.rb:119

This error was reported at [ruby-core:4775], and I posted patch at [ruby-core:4793].
But that patch was slower than original one, so I reimplemented.

Does this patch help you? (I hope calculation is correct)

Index: profiler.rb

···

===================================================================
RCS file: /src/ruby/lib/profiler.rb,v
retrieving revision 1.1
diff -u -w -b -p -r1.1 profiler.rb
--- profiler.rb 20 Dec 2002 09:00:10 -0000 1.1
+++ profiler.rb 29 Apr 2005 14:51:52 -0000
@@ -1,40 +1,29 @@
module Profiler__
- Times = if defined? Process.times then Process else Time end
   # internal values
   @@start = @@stack = @@map = nil
   PROFILE_PROC = proc{|event, file, line, id, binding, klass|
     case event
     when "call", "c-call"
- now = Float(Times::times[0])
- @@stack.push [now, 0.0, id]
+ now = Float(Process.times[0])
+ @@stack.push [now, 0.0]
     when "return", "c-return"
- now = Float(Times::times[0])
- tick = @@stack.pop
- name = klass.to_s
- if name.nil? then name = '' end
- if klass.kind_of? Class
- name += "#"
- else
- name += "."
- end
- name += id.id2name
- data = @@map[name]
- unless data
- data = [0.0, 0.0, 0.0, name]
- @@map[name] = data
- end
+ now = Float(Process.times[0])
+ key = [klass, id]
+ if tick = @@stack.pop
+ data = (@@map[key] ||= [0, 0.0, 0.0, key])
       data[0] += 1
       cost = now - tick[0]
       data[1] += cost
       data[2] += cost - tick[1]
- @@stack[-1][1] += cost
+ @@stack[-1][1] += cost if @@stack[-1]
+ end
     end
   }
module_function
   def start_profile
- @@start = Float(Times::times[0])
- @@stack = [[0, 0, :toplevel], [0, 0, :dummy]]
- @@map = {"#toplevel" => [1, 0, 0, "#toplevel"]}
+ @@start = Float(Process.times[0])
+ @@stack =
+ @@map = {}
     set_trace_func PROFILE_PROC
   end
   def stop_profile
@@ -42,9 +31,8 @@ module_function
   end
   def print_profile(f)
     stop_profile
- total = Float(Times::times[0]) - @@start
+ total = Float(Process.times[0]) - @@start
     if total == 0 then total = 0.01 end
- @@map["#toplevel"][1] = total
     data = @@map.values
     data.sort!{|a,b| b[2] <=> a[2]}
     sum = 0
@@ -53,7 +41,19 @@ module_function
     for d in data
       sum += d[2]
       f.printf "%6.2f %8.2f %8.2f %8d ", d[2]/total*100, sum, d[2], d[0]
- f.printf "%8.2f %8.2f %s\n", d[2]*1000/d[0], d[1]*1000/d[0], d[3]
+ f.printf "%8.2f %8.2f %s\n", d[2]*1000/d[0], d[1]*1000/d[0], get_name(*d[3])
+ end
+ f.printf "%6.2f %8.2f %8.2f %8d ", 0.0, total, 0.0, 1
+ f.printf "%8.2f %8.2f %s\n", 0.0, total*1000, "#toplevel"
+ end
+ def get_name(klass, id)
+ name = klass.to_s || ""
+ if klass.kind_of? Class
+ name += "#"
+ else
+ name += "."
     end
+ name + id.id2name
   end
+ private :get_name
end

Hi there,

>I have some code which I wanted to run under the profiler but it's
>raising an error within the profiler code:
>
This error was reported at [ruby-core:4775], and I posted patch at [ruby-core:4793].
But that patch was slower than original one, so I reimplemented.

Does this patch help you? (I hope calculation is correct)

Thanks for your answer and sending the patch. I'm afraid that I
cannot make it work though, despite help from the #ruby-lang crew, the
best I can do is:

patching file `profiler.rb'
patch unexpectedly ends in middle of line
patch unexpectedly ends in middle of line

the suggestion from the gang in IRC being that indentation or
something is wrong in the patch. I'm saving it from a plain text
version of your post -- maybe it's getting messed up by GMail?

Can you please send me a copy via email as a plain text attachment?

Many thanks,

Matt

···

On 4/29/05, H. Yamamoto <ocean@m2.ccsnet.ne.jp> wrote:

--
Matt Mower :: http://matt.blogs.it/

Can you please send me a copy via email as a plain text attachment?

OK, this is a small file, so I'll attach the file itself.

profiler.rb (1.63 KB)

And probably thread support version is here. (slower than previous one a little)

profiler.rb (1.63 KB)

Many thanks, the patched version works a treat :wink:

M

···

On 4/30/05, H. Yamamoto <ocean@m2.ccsnet.ne.jp> wrote:

>Can you please send me a copy via email as a plain text attachment?

OK, this is a small file, so I'll attach the file itself.

--
Matt Mower :: http://matt.blogs.it/

And probably thread support version is here. (slower than previous one a little)

Oops, sorry. post miss.... This is really thread supported version.

profiler.rb (1.8 KB)