Bug #16351
Updated by nobu (Nobuyoshi Nakada) about 5 years ago
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`, Object, using plain params, using a hash and using keyword arguments. ```ruby ``` 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` FooWithPlainParams not surprisingly just reported "Total allocated: 4000 bytes (100 objects)". `FooWithOptionsHash` FooWithOptionsHash reported "Total allocated: 27200 bytes (200 objects)" with 100 `Hash` Hash allocations. This makes sense, since the params are passed on as a `Hash`. Hash. `FooWithKeywordArguments` FooWithKeywordArguments reported "Total allocated: 50400 bytes (300 objects)" with 200 `Hash` Hash allocations, which is a bit surprising. After that I checked out ruby-head and there `FooWithKeywordArguments.new` FooWithKeywordArguments.new reports only 100 `Hash` Hash allocations as `FooWithOptionsHash`. 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. ```ruby ``` 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` FooWithKeyword object, does not show any allocations. What is the difference here between `foo` and `initialize`?