fastruby / fast-ruby

:dash: Writing Fast Ruby :heart_eyes: -- Collect Common Ruby idioms.
https://github.com/fastruby/fast-ruby
5.67k stars 376 forks source link

Hash#fetch with argument vs Hash#fetch + block #39

Closed mnarayan01 closed 9 years ago

mnarayan01 commented 9 years ago

This one seems a bit misleading. Simply switching the default to e.g. a symbol or constant-defined string makes both versions perform essentially identically (the argument version is actually slightly faster).

The difference in the current version is (AFAIK) exclusively due to the time taken to allocate the string (which is elided in the block version). This makes the displayed time comparison quite misleading (at least from my perspective), as the ratio can be increased/decreased at will be changing the runtime of the default expression.

mnarayan01 commented 9 years ago

Also I guess it's worth noting that if the fetch misses, the argument version is always faster.

ixti commented 9 years ago

@mnarayan01 Difference in those two forms is that in case of:

obj.fetch("foo", "bar")

you are creating two String objects always, while in case of

obj.fetch("foo") { "bar" }

one String is created, and second one created only if Hash has no such key.

So, of course if your default value is a constant, block-less form is a pure win:

BAR = "bar".freeze

obj.fetch("foo", nil)
obj.fetch("foo", :bar)
obj.fetch("foo", BAR)

# etc...
JuanitoFatas commented 9 years ago

@ixti Thanks for your explanations! :musical_note:

@mnarayan01 Thank you for bringining this! Does @ixti's reply clear your concerns? Do you have suggestions on improving current example code? Thanks! :bow:

ixti commented 9 years ago

@JuanitoFatas yeah, I guess link to this issue is the simplest way :D Thanks!

mnarayan01 commented 9 years ago

Yea think it's perfect now. :+1: