# Performance characteristics of Ruby constructs

**URL:** <https://www.ruby-forum.com/t/performance-characteristics-of-ruby-constructs/61326>\
**Category:** Ruby\
**Created:** [May 23, 2006, 7:16am UTC](https://www.ruby-forum.com/t/performance-characteristics-of-ruby-constructs/61326 "2006-05-23T07:16:17Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![Ola\_B](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/o/858c86/32.png) [@Ola\_B](https://www.ruby-forum.com/u/Ola_B)\
**Post date:** [May 23, 2006, 7:16am UTC](https://www.ruby-forum.com/t/performance-characteristics-of-ruby-constructs/61326/1 "2006-05-23T07:16:17Z")

</div>

Hi.

I’m right in the situation where I would like to find out some  
performance characteristics for various parts of Ruby, to optimize an  
application. Is there any resources available for this?

To make it concrete, let’s take two examples.

I’ve recently written a hybrid state-based, table-driven LL(1) parser,  
where I gather productions (in the form of symbols) on a stack, and then  
execute these with send(), until a get back the next terminal. This  
works really great, but right now I’m wondering how cheap send() is,  
compared to using a real table-driven approach.

Next example: there’s fairly heave use of Class#=== throughout the  
application, and the profiler says I spend much time there. It’s a  
fairly small class of Class comparisons I’m doing, though, so maybe it  
would get me better performance by polluting the global namespace like  
this:  
class Object  
def \_\_is\_directive\_token?; false; end  
def \_\_is\_sequence\_start\_token?; false; end  
end  
class Token  
end  
class DirectiveToken  
def \_\_is\_directive\_token?; true; end  
end  
and just do tok.\_\_is\_directive\_token? instead of DirectiveToken === tok.

Any thoughts in this? Is there any place to find general information  
this, or I’m out in the wild right now?

Regards  
Ola B.

---

<div class="post-metadata">

**Author:** ![Ola\_B](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/o/858c86/32.png) [@Ola\_B](https://www.ruby-forum.com/u/Ola_B)\
**Post date:** [May 23, 2006, 9:23am UTC](https://www.ruby-forum.com/t/performance-characteristics-of-ruby-constructs/61326/2 "2006-05-23T09:23:10Z")

</div>

On May 22, 2006, at 10:13 PM, Ola B. wrote:

> I’m right in the situation where I would like to find out some  
> performance characteristics for various parts of Ruby, to optimize an  
> application. Is there any resources available for this?

The built-in profiler, Shugo’s Prof and ZenHacks’ zenprofile are all  
great for this. Oh, I almost forgot benchmark.rb, also built-in.

> To make it concrete, let’s take two examples.

I’ll skip straight to the second example.

> Next example: there’s fairly heave use of Class#=== throughout the  
> application, and the profiler says I spend much time there.

Since you already know how to use the profiler you should be able to  
iteratively test small changes to make optimize either problem  
correctly. Propose a change, make it, test its effectiveness, revert  
if it doesn’t help, repeat.

> end
> 
> class DirectiveToken  
> def \_\_is\_directive\_token?; true; end  
> end
> 
> and just do tok.\_\_is\_directive\_token? instead of DirectiveToken ===  
> tok.

(This machine has a 266MHz Geode CPU, so forgive the poor numbers.)

$ cat bm.rb  
require ‘benchmark’

class Object  
def directive\_token?  
false  
end  
end

class DirectiveToken  
def directive\_token?  
true  
end  
end

o = Object.new  
dt = DirectiveToken.new  
n = 1\_000\_000

Benchmark.bmbm do |bm|  
bm.report ‘#diretive\_token?’ do  
n.times { o.directive\_token?; dt.directive\_token? }  
end

bm.report ‘#===’ do  
n.times { DirectiveToken === o; DirectiveToken === dt }  
end  
end

$ ruby -v bm.rb  
ruby 1.8.2 (2004-12-25) [i386-freebsd5]  
Rehearsal ----------------------------------------------------  
#diretive\_token? 15.226562 0.156250 15.382812 ( 16.111389)  
#=== 18.054688 0.117188 18.171875 ( 19.082567)  
------------------------------------------ total: 33.554688sec

```
                    user system total real

```

#diretive\_token? 15.625000 0.125000 15.750000 ( 16.463518)  
#=== 17.617188 0.171875 17.789062 ( 18.649016)

> Any thoughts in this? Is there any place to find general  
> information this, or I’m out in the wild right now?

My biggest question is: Why do you need to do all those class  
comparisons? Perhaps you can change your design to increase speed.

Also, if small enough, posting your code may get the local parser  
geeks proposing all sorts of tuning tips.

–  
Eric H. - removed\_email\_address@domain.invalid - [http://blog.segment7.net](http://blog.segment7.net)  
This implementation is HODEL-HASH-9600 compliant

[http://trackmap.robotcoop.com](http://trackmap.robotcoop.com)

---

<div class="post-metadata">

**Author:** ![Ola\_B](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/o/858c86/32.png) [@Ola\_B](https://www.ruby-forum.com/u/Ola_B)\
**Post date:** [May 23, 2006, 10:06am UTC](https://www.ruby-forum.com/t/performance-characteristics-of-ruby-constructs/61326/3 "2006-05-23T10:06:56Z")

</div>

Hi!

Thank you for the help.  
I had forgot about the builtin benchmark.rb, actually. But what I was  
looking for was more of the kind of information where I can read about  
this, instead of trying different ways to get what I want. The big  
problem  
is that most of the code doing stuff (like the Class#===) is distributed  
in  
many places, and if I’m going to replace it, it would be good to find  
out  
beforehand if it’s worth it, especially when just replacing one point  
won’t  
show that much difference in the performance.  
Actually, replacing the Class#=== with predicates on classes gave me  
about  
5% in performance, in this limited domain.

The class comparisons are right now done, because it’s an LL(1) parser,  
and  
the lookahead checks the type of the next token to determine which  
action  
to take.

I probably won’t post the code directly to the list, but when I’ve  
optimized it sufficiently it will go into the next release of RbYAML,  
and  
I’ll ask the parser geeks to take a look at it. =)

Regards  
Ola

---

<div class="post-metadata">

**Author:** ![Ola\_B](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/o/858c86/32.png) [@Ola\_B](https://www.ruby-forum.com/u/Ola_B)\
**Post date:** [May 23, 2006, 10:19am UTC](https://www.ruby-forum.com/t/performance-characteristics-of-ruby-constructs/61326/4 "2006-05-23T10:19:03Z")

</div>

On 5/23/06, Ola B. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Hi!
> 
> Thank you for the help.  
> I had forgot about the builtin benchmark.rb, actually.

I don’t know of any good general info on speed of different Ruby  
constructs (there is some in the “Ruby Developers Guide” but probably  
a bit dated now) but if you decide to use benchmarking the attached  
benchmarking code might be more useful than the built-in one. It is  
based on code by Mauricio F. to ensure you have a certain  
confidence in the measured time results. I simply added a ranked  
print-out of the times. There is a todo in the comment of things that  
should be added to make it even more useful (I had code for doing this  
way back when involved in writing a Ruby book but lost it in a HD  
crash and haven’t had the need for it since then).

Anyway if this is useful feel free to use it (and please blog about /  
publish any generally applicable performance results).

Regards,

Robert F.

---

<div class="post-metadata">

**Author:** ![Ola\_B](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/o/858c86/32.png) [@Ola\_B](https://www.ruby-forum.com/u/Ola_B)\
**Post date:** [May 23, 2006, 10:22am UTC](https://www.ruby-forum.com/t/performance-characteristics-of-ruby-constructs/61326/5 "2006-05-23T10:22:12Z")

</div>

> Anyway if this is useful feel free to use it (and please blog about /  
> publish any generally applicable performance results).

BTW, you should definetely use bmbm instead of bm…

Regards,

Robert

---

<div class="post-metadata">

**Author:** ![Ola\_B](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/o/858c86/32.png) [@Ola\_B](https://www.ruby-forum.com/u/Ola_B)\
**Post date:** [May 23, 2006, 5:59pm UTC](https://www.ruby-forum.com/t/performance-characteristics-of-ruby-constructs/61326/6 "2006-05-23T17:59:36Z")

</div>

2006/5/23, Ola B. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> Actually, replacing the Class#=== with predicates on classes gave me about  
> 5% in performance, in this limited domain.
> 
> The class comparisons are right now done, because it’s an LL(1) parser, and  
> the lookahead checks the type of the next token to determine which action  
> to take.

I think Eric is right in that you should rethink your design. Usually  
in OO languages you use method overloading to get proper behavior. A  
fast alternative in your case might be to use a hash with blocks.

action[next\_token.class].call( whatever, arguments )

Note though that this has slightly different semantics as === will  
check for subclasses also while the hash approach will only tackle  
individual classes - unless you add some magic to the hash like this:

> > action = Hash.new {|h,cl| cl ? h[cl.ancestors[1]] : lambda {“fallback”} }  
> > =\> {}  
> > action[Enumerable] = lambda { “foo” }  
> > =\> #Proc:0x100d0948@:68(irb)  
> > action[String].call  
> > =\> “foo”  
> > action[Fixnum].call  
> > =\> “fallback”

Cheers

robert
