ruby/hash.rb
Jean Boussier 9594db0cf2 Implement Hash.new(capacity:)
[Feature #19236]

When building a large hash, pre-allocating it with enough
capacity can save many re-hashes and significantly improve
performance.

```
/opt/rubies/3.3.0/bin/ruby --disable=gems -rrubygems -I./benchmark/lib ./benchmark/benchmark-driver/exe/benchmark-driver \
	            --executables="compare-ruby::../miniruby-master -I.ext/common --disable-gem" \
	            --executables="built-ruby::./miniruby --disable-gem" \
	            --output=markdown --output-compare -v $(find ./benchmark -maxdepth 1 -name 'hash_new' -o -name '*hash_new*.yml' -o -name '*hash_new*.rb' | sort)
compare-ruby: ruby 3.4.0dev (2024-03-25T11:48:11Z master f53209f023) +YJIT dev [arm64-darwin23]
last_commit=[ruby/irb] Cache RDoc::RI::Driver.new (https://github.com/ruby/irb/pull/911)
built-ruby: ruby 3.4.0dev (2024-03-25T15:29:40Z hash-new-rb 77652b08a2) +YJIT dev [arm64-darwin23]
warming up...

|                    |compare-ruby|built-ruby|
|:-------------------|-----------:|---------:|
|new                 |      7.614M|    5.976M|
|                    |       1.27x|         -|
|new_with_capa_1k    |     13.931k|   15.698k|
|                    |           -|     1.13x|
|new_with_capa_100k  |     124.746|   148.283|
|                    |           -|     1.19x|
```
2024-07-08 12:24:33 +02:00

40 lines
1.6 KiB
Ruby

class Hash
# call-seq:
# Hash.new(default_value = nil) -> new_hash
# Hash.new(default_value = nil, capacity: size) -> new_hash
# Hash.new {|hash, key| ... } -> new_hash
# Hash.new(capacity: size) {|hash, key| ... } -> new_hash
#
# Returns a new empty +Hash+ object.
#
# The initial default value and initial default proc for the new hash
# depend on which form above was used. See {Default Values}[rdoc-ref:Hash@Default+Values].
#
# If neither an argument nor a block is given,
# initializes both the default value and the default proc to <tt>nil</tt>:
# h = Hash.new
# h.default # => nil
# h.default_proc # => nil
#
# If argument <tt>default_value</tt> is given but no block is given,
# initializes the default value to the given <tt>default_value</tt>
# and the default proc to <tt>nil</tt>:
# h = Hash.new(false)
# h.default # => false
# h.default_proc # => nil
#
# If a block is given but no <tt>default_value</tt>, stores the block as the default proc
# and sets the default value to <tt>nil</tt>:
# h = Hash.new {|hash, key| "Default value for #{key}" }
# h.default # => nil
# h.default_proc.class # => Proc
# h[:nosuch] # => "Default value for nosuch"
#
# If both a block and a <tt>default_value</tt> are given, raises an +ArgumentError+
#
# If the optional keyword argument +capacity+ is given, the hash will be allocated
# with enough capacity to accomodate this many keys without having to be resized.
def initialize(ifnone = (ifnone_unset = true), capacity: 0, &block)
Primitive.rb_hash_init(capacity, ifnone_unset, ifnone, block)
end
end