Robert Klemme
10/17/2007 5:59:00 AM
On 16.10.2007 19:05, Alex Fenton wrote:
> Wayne Magor wrote:
>> I have a script in which I was using a 2-element array where a struct
>> would be used in another language, so I decided to give the Ruby class
>> Struct a try.
>>
>> My script went from taking 2 seconds to taking 27 seconds from this
>> simple change!
>
> This doesn't sound likely, even if your script did nothing else but use
> the Struct class. I'd look elsewhere for the source of slowness (try
> running your script with -rprofile).
>
> A quick benchmark suggests that Struct is somewhat slower to instantiate
> (+100%), marginally slower to set values in (+33%), and the same speed
> to fetch values from as an Array:
>
> BENCHMARK:
>
> require 'benchmark'
>
> GC.disable
> Foo = Struct.new(:foo, :bar)
>
> repetitions = 500_000
>
> puts 'struct-init', Benchmark::measure {
> repetitions.times { f = Foo.new('x', 666) }
> }
>
> puts 'array-init', Benchmark::measure {
> repetitions.times { f = ['x', 666] }
> }
>
> puts 'struct-get', Benchmark::measure {
> f = Foo.new('x', 666)
> repetitions.times { g = f.foo }
> }
>
> puts 'array-get', Benchmark::measure {
> f = ['x', 666]
> repetitions.times { g = f[0] }
> }
>
> puts 'struct-set', Benchmark::measure {
> f = Foo.new('x', 666)
> repetitions.times { f.foo = 'y' }
> }
>
> puts 'array-set', Benchmark::measure {
> f = ['x', 666]
> repetitions.times { f[0] = 'y' }
> }
>
>
> __END__
>
> RESULTS (ruby 1.8.4 (2005-12-24) [i386-mswin32])
>
> struct-init
> 1.359000 0.031000 1.390000 ( 1.390000)
> array-init
> 0.563000 0.016000 0.579000 ( 0.579000)
> struct-get
> 0.281000 0.000000 0.281000 ( 0.281000)
> array-get
> 0.297000 0.000000 0.297000 ( 0.297000)
> struct-set
> 0.422000 0.000000 0.422000 ( 0.422000)
> array-set
> 0.281000 0.000000 0.281000 ( 0.281000)
I'm not sure whether you are familiar with Benchmark#bmbm which does a
rehearsal - personally I rather not switch off GC since in realistic
situations GC time belongs into the mix. But results are rather similar:
Robert@Babelfish2 /cygdrive/c/TEMP
$ ruby array-struct.rb
Rehearsal --------------------------------------------------
struct init 3.812000 0.000000 3.812000 ( 3.923000)
array init 1.672000 0.000000 1.672000 ( 1.709000)
struct get 0.437000 0.000000 0.437000 ( 0.440000)
array get 0.485000 0.000000 0.485000 ( 0.485000)
struct set 0.718000 0.000000 0.718000 ( 0.716000)
array set 0.500000 0.000000 0.500000 ( 0.510000)
----------------------------------------- total: 7.624000sec
user system total real
struct init 3.891000 0.000000 3.891000 ( 3.984000)
array init 1.640000 0.000000 1.640000 ( 1.690000)
struct get 0.438000 0.000000 0.438000 ( 0.450000)
array get 0.469000 0.000000 0.469000 ( 0.469000)
struct set 0.703000 0.000000 0.703000 ( 0.715000)
array set 0.484000 0.000000 0.484000 ( 0.504000)
Robert@Babelfish2 /cygdrive/c/TEMP
$ cat array-struct.rb
require 'benchmark'
REP = 500_000
Foo = Struct.new :foo, :bar
data = "foo"
c1 = Foo.new data, data
c2 = [data, data]
Benchmark.bmbm 15 do |x|
x.report 'struct init' do
REP.times { Foo.new data, data }
end
x.report 'array init' do
REP.times { [data, data] }
end
x.report 'struct get' do
REP.times { c1.bar }
end
x.report 'array get' do
REP.times { c2[1] }
end
x.report 'struct set' do
REP.times { c1.bar = data }
end
x.report 'array set' do
REP.times { c2[1] = data }
end
end
Kind regards
robert