Bug #16351
closedWhy do Keyword arguments to initialize allocate a Hash, but not for other methods?
Description
Hello, while working on improving memory allocations in one of my apps, I stumbled upon the following behavior. I measured three different ways of passing variables to a new Object
, using plain params, using a hash and using keyword arguments.
class FooWithPlainParams
def initialize(a, b, c)
@a = a
@b = b
@c = c
end
end
class FooWithOptionsHash
def initialize(options = {})
@a = options[:a]
@b = options[:b]
@c = options[:c]
end
end
class FooWithKeyword
def initialize(a:, b:, c:)
@a = a
@b = b
@c = c
end
end
I used memory_profiler gem to measure the allocations with the attached script, calling new 100 times, using ruby 2.6.5p114 (2019-10-01 revision 67812) [x86_64-darwin19]
FooWithPlainParams
not surprisingly just reported "Total allocated: 4000 bytes (100 objects)".
FooWithOptionsHash
reported "Total allocated: 27200 bytes (200 objects)" with 100 Hash
allocations. This makes sense, since the params are passed on as a Hash
.
FooWithKeywordArguments
reported "Total allocated: 50400 bytes (300 objects)" with 200 Hash
allocations, which is a bit surprising.
After that I checked out ruby-head and there FooWithKeywordArguments.new
reports only 100 Hash
allocations as FooWithOptionsHash
. So that part seems to be fixed.
What surprised me so was, that using the same way of passing parameters in another method, resulted in no allocated Hash according to memory_profiler gem.
class FooWithKeyword
def foo(d:, e:, f:)
@d = d; @e = e; @f = f
end
end
Calling foo(d: 4, e: 5, f: 6)
on a FooWithKeyword
object, does not show any allocations.
What is the difference here between foo
and initialize
?
Files