I wasn't going to get into benchmarking this one, but ...

On Sun, 2006-02-19 at 12:45 +0900, Eero Saynatkari wrote:
> On 2006.02.19 10:30, Wilson Bilkovich wrote:
> > On 2/18/06, Timothy Goddard <interfecus / gmail.com> wrote:
> > > To take the focus off number of lines, let's take a look at bechmarks.
> > > This was my benchmark script:
> > >
> > > Benchmark::bm(12) do |x|
> > >   x.report('attr') {100000.times {c = Class.new {attr :foo, :bar}}}
> > >   x.report('attribute') {100000.times {c = Class.new {attribute :foo,
> > > :bar}}}
> > > end
> > >
> > > And my results were:
> > >
> > >                   user     system      total        real
> > > attr          3.720000   0.000000   3.720000 (  3.724316)
> > > attribute    25.750000   0.000000  25.750000 ( 25.790665)
> > >
> > > It isn't that efficient, but I'd like to see how it compares.
> > >
> > 
> > That's interesting. I didn't expect the difference to be quite this
> > big.  attr is impressively fast.
> >                   user     system      total        real
> > attr          7.250000   0.000000   7.250000 (  7.250000)
> > attribute    30.110000   0.000000  30.110000 ( 30.172000)
> > 
> > I'm looking forward to seeing some of the other solutions, for sure. 
> > I had my hands halfway around a faster way, but couldn't quite make it
> > work.
> 
> Yours actually looks very good. My first attempt is quite a bit off:
> 
>                     user     system      total        real
>   attr          7.117188   0.000000   7.117188 (  7.381454)
>   attribute    38.835938   0.031250  38.867188 ( 41.244430)
> 
> To factor out some machine differential, mine works out to be about
> 5.46 times slower, yours is 4.15 and Timothy is at 7.45. Another 
> interesting tidbit is that attr_accessor is about 1.5 to 2 times
> slower than attr.
> 

I think maybe there is some confusion over the operation of 'attr' here,
the test above defines a single attribute, :foo. The second argument to
'attr' is evaluated as boolean, and determines whether a writer is
created also. So the test will make foo and foo= but not bar or bar= .
Consider the following IRB:

	class C
	  attr :one, :two
	end
	# => nil

	c = C.new
	# => #<C:0xb7e34534>

	c.one
	# => nil
	c.one = 'one'
	# => "one"
	c.two
	NoMethodError: undefined method `two' for #<C:0xb7e34534>
	        from (irb):11

> >From another standpoint, it might be interesting to look at 
> access and update speeds. Here is the script:
> 
>   require 'benchmark'
>   require 'knowledge'
> 
>   Benchmark.bm {|b|
>     b.report('attr_accessor') {c = Class.new {attr_accessor :foo}.new; c.foo = 2; 100_000.times {c.foo}}
>     b.report('attribute-plain') {c = Class.new {attribute :foo}.new; c.foo = 2; 100_000.times {c.foo}}
>     b.report('attribute-default') {c = Class.new {attribute(:foo) {2}}.new; 100_000.times {c.foo}}
>   }
> 
>                          user     system      total        real
>   attr_accessor      0.046875   0.000000   0.046875 (  0.052311)
>   attribute-plain    0.343750   0.000000   0.343750 (  0.364738)
>   attribute-default  0.460938   0.000000   0.460938 (  0.474879)
>       
> So there is clear order-of-magnitude difference there.

After modifying the original benchmark to use attr_accessor (for
completeness really, they're all implemented in C AFAIK so comparison is
pretty futile from the start ;)) and adding in the code above, I get:

### Creation ###
                          user     system      total        real
attr                  4.930000   0.040000   4.970000 (  5.066622)
attribute            16.080000   0.130000  16.210000 ( 16.429639)

### Use ###
                          user     system      total        real
attr_accessor         0.080000   0.010000   0.090000 (  0.123403)
attribute-plain       0.730000   0.000000   0.730000 (  0.777927)
attribute-default     0.700000   0.010000   0.710000 (  0.755691)

-- 
Ross Bamford - rosco / roscopeco.REMOVE.co.uk