Why {} is much faster than Hash.new ?

Discussion in 'Ruby' started by Iñaki Baz Castillo, Jan 13, 2011.

  1. Hi, a simple benchmark:

    Benchmark.realtime { 1000000.times { @m =3D Hash.new } }
    =3D> 0.6552023887634277

    Benchmark.realtime { 1000000.times { @m =3D {} } }
    =3D> 0.17668819427490234

    I would like to know why {} is so much faster. I can understand that
    Hash.initialize method must inspect is an argument is given and so, is
    just due to it?

    Thanks.


    --=20
    I=C3=B1aki Baz Castillo
    <>
    Iñaki Baz Castillo, Jan 13, 2011
    #1
    1. Advertising

  2. On Thu, Jan 13, 2011 at 12:05 PM, I=F1aki Baz Castillo <> wrot=
    e:
    > Hi, a simple benchmark:
    >
    > Benchmark.realtime { 1000000.times { @m =3D Hash.new } }
    > =3D> 0.6552023887634277
    >
    > Benchmark.realtime { 1000000.times { @m =3D {} } }
    > =3D> 0.17668819427490234
    >
    > I would like to know why {} is so much faster. I can understand that
    > Hash.initialize method must inspect is an argument is given and so, is
    > just due to it?


    I can imagine that's about right. Another benchmark:

    13:10:40 Temp$ ruby19 bm.rb
    Rehearsal --------------------------------------------------
    Hash.new 1.297000 0.000000 1.297000 ( 1.293000)
    Hash 0.125000 0.000000 0.125000 ( 0.127000)
    Hash.nil? 0.187000 0.000000 0.187000 ( 0.186000)
    {} 0.188000 0.000000 0.188000 ( 0.191000)
    ----------------------------------------- total: 1.797000sec

    user system total real
    Hash.new 1.296000 0.000000 1.296000 ( 1.292000)
    Hash 0.125000 0.000000 0.125000 ( 0.127000)
    Hash.nil? 0.188000 0.000000 0.188000 ( 0.185000)
    {} 0.187000 0.000000 0.187000 ( 0.191000)
    13:10:50 Temp$ cat bm.rb
    require 'benchmark'

    R =3D 1_000_000

    Benchmark.bmbm 15 do |b|
    b.report "Hash.new" do
    R.times { Hash.new }
    end

    b.report "Hash" do
    R.times { Hash }
    end

    b.report "Hash.nil?" do
    R.times { Hash.nil? }
    end

    b.report "{}" do
    R.times { {} }
    end
    end
    13:10:52 Temp$

    Cheers

    robert

    --=20
    remember.guy do |as, often| as.you_can - without end
    http://blog.rubybestpractices.com/
    Robert Klemme, Jan 13, 2011
    #2
    1. Advertising

  3. I think it's the cost of the method call with options parsing.

    Benchmark.realtime do 1_000_000.times do @m =3D Hash.new end end
    =3D> 1.1976041793823242

    def blank_method; end
    Benchmark.realtime do 1_000_000.times do @m =3D blank_method end end
    =3D> 0.1965808868408203

    Benchmark.realtime do 1_000_000.times do @m =3D {} end end
    =3D> 0.2893531322479248

    Benchmark.realtime do 1_000_000.times do @m =3D Hash.allocate end end
    =3D> 0.3925323486328125

    You see that Hash.allocate's time is about the same as ({} +
    blank_method). The rest comes from option parsing I guess.

    2011/1/13 I=C3=B1aki Baz Castillo <>:
    > Hi, a simple benchmark:
    >
    > Benchmark.realtime { 1000000.times { @m =3D Hash.new } }
    > =3D> 0.6552023887634277
    >
    > Benchmark.realtime { 1000000.times { @m =3D {} } }
    > =3D> 0.17668819427490234
    >
    > I would like to know why {} is so much faster. I can understand that
    > Hash.initialize method must inspect is an argument is given and so, is
    > just due to it?
    >
    > Thanks.
    >
    >
    > --
    > I=C3=B1aki Baz Castillo
    > <>
    >
    >
    Jonas Pfenniger (zimbatm), Jan 13, 2011
    #3
  4. 2011/1/13 Jonas Pfenniger (zimbatm) <>:
    > I think it's the cost of the method call with options parsing.
    >
    > Benchmark.realtime do 1_000_000.times do @m =3D Hash.new end end
    > =C2=A0=3D> 1.1976041793823242
    >
    > def blank_method; end
    > Benchmark.realtime do 1_000_000.times do @m =3D blank_method end end
    > =C2=A0=3D> 0.1965808868408203
    >
    > Benchmark.realtime do 1_000_000.times do @m =3D {} end end
    > =C2=A0=3D> 0.2893531322479248
    >
    > Benchmark.realtime do 1_000_000.times do @m =3D Hash.allocate end end
    > =C2=A0=3D> 0.3925323486328125
    >
    > You see that Hash.allocate's time is about the same as ({} +
    > blank_method). The rest comes from option parsing I guess.


    Good point :)

    Thanks a lot.




    --=20
    I=C3=B1aki Baz Castillo
    <>
    Iñaki Baz Castillo, Jan 13, 2011
    #4
  5. Iñaki Baz Castillo

    Ryan Davis Guest

    On Jan 13, 2011, at 03:05 , I=F1aki Baz Castillo wrote:

    > Benchmark.realtime { 1000000.times { @m =3D Hash.new } }
    > =3D> 0.6552023887634277
    >=20
    > Benchmark.realtime { 1000000.times { @m =3D {} } }
    > =3D> 0.17668819427490234


    % echo "{}" | parse_tree_show
    s:)hash)

    % echo "Hash.new" | parse_tree_show
    s:)call, s:)const, :Hash), :new, s:)arglist))
    Ryan Davis, Jan 13, 2011
    #5
  6. Iñaki Baz Castillo

    Roger Pack Guest

    > I think it's the cost of the method call with options parsing.

    You'd think they'd be able to optimize that , if that's the case...

    -r

    --
    Posted via http://www.ruby-forum.com/.
    Roger Pack, Jan 17, 2011
    #6
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Mr. SweatyFinger
    Replies:
    2
    Views:
    1,733
    Smokey Grindel
    Dec 2, 2006
  2. Sanny
    Replies:
    12
    Views:
    568
    Andrew Thompson
    Dec 15, 2006
  3. Stef Mientki

    Wow, Python much faster than MatLab

    Stef Mientki, Dec 29, 2006, in forum: Python
    Replies:
    11
    Views:
    647
    sturlamolden
    Jan 1, 2007
  4. Replies:
    13
    Views:
    692
    Dr.Ruud
    Jul 19, 2006
  5. Melzzzzz
    Replies:
    39
    Views:
    1,823
    Melzzzzz
    Jul 29, 2012
Loading...

Share This Page