Skip to content

Commit

Permalink
Implement Hash.new(capacity:)
Browse files Browse the repository at this point in the history
[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 (ruby/irb#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|
```
  • Loading branch information
byroot authored and headius committed Nov 5, 2024
1 parent 7f5997d commit 61d19b0
Showing 1 changed file with 19 additions and 1 deletion.
20 changes: 19 additions & 1 deletion core/hash/new_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
-> { Hash.new(nil) { 0 } }.should raise_error(ArgumentError)
end

ruby_version_is "3.3" do
ruby_version_is "3.3"..."3.4" do
it "emits a deprecation warning if keyword arguments are passed" do
-> { Hash.new(unknown: true) }.should complain(
Regexp.new(Regexp.escape("Calling Hash.new with keyword arguments is deprecated and will be removed in Ruby 3.4; use Hash.new({ key: value }) instead"))
Expand All @@ -46,4 +46,22 @@
Hash.new({ unknown: true }).default.should == { unknown: true }
end
end

ruby_version_is "3.4" do
it "accepts a capacity: argument" do
Hash.new(5, capacity: 42).default.should == 5
Hash.new(capacity: 42).default.should == nil
(Hash.new(capacity: 42) { 1 }).default_proc.should_not == nil
end

it "ignores negative capacity" do
-> { Hash.new(capacity: -42) }.should_not raise_error
end

it "raises an error if unknown keyword arguments are passed" do
-> { Hash.new(unknown: true) }.should raise_error(ArgumentError)
-> { Hash.new(1, unknown: true) }.should raise_error(ArgumentError)
-> { Hash.new(unknown: true) { 0 } }.should raise_error(ArgumentError)
end
end
end

0 comments on commit 61d19b0

Please sign in to comment.