From: Robert Klemme Date: 2007-10-17T15:00:08+09:00 Subject: Re: Struct is slow 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