Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Add Hash#values_at vs Array#map { Hash#[] } comparison #174

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
kewlar wants to merge 6 commits into fastruby:main
base: main
Choose a base branch
Loading
from kewlar:hash-values_at

Conversation

@kewlar
Copy link

@kewlar kewlar commented Mar 14, 2019

No description provided.

Copy link
Author

kewlar commented Mar 14, 2019

DO NOT MERGE YET.

Just noticed that #values_at and #slice#values return different results when Hash members are missing 🤦‍♂️

Will update the code and the benchmark, and see if it's still worth merging.

Copy link
Collaborator

This is faster than slice on my machine and returns the same as values_at:

KEYS.map{ |key| HASH[key] }
kewlar reacted with thumbs up emoji

Copy link
Author

kewlar commented Mar 14, 2019

@Arcovion, cool! Will add it to the benchmark, too. Thanks!

Copy link
Author

kewlar commented Mar 21, 2019
edited
Loading

Added more ways of slicing Hash values, and organized them into three separate cases:

  • when all keys are expected to exist in the Hash (Hash#values_at);
  • when some keys may not exist in the Hash, and we care about the non-existing keys (Hash#values_at);
  • when some keys may not exist in the Hash, and we care only about the existing keys (Hash#slice#values).

Thoughts?

Copy link
Member

@kewlar I see the value in adding code/hash/values_at-vs-map.rb because it is quite straightforward and natural. But I don't see the value in adding the other benchmarks. The other examples are doing too many things and it is hard to tell which part makes one slower than the other.

I'm happy to add code/hash/values_at-vs-map.rb if you submit just that in this PR or another PR.

@kewlar kewlar changed the title (削除) Add Hash#values_at vs Hash#slice#values comparison (削除ここまで) (追記) Add Hash#values_at vs Array#map { Hash#[] } comparison (追記ここまで) Mar 2, 2023
Copy link
Author

kewlar commented Mar 2, 2023

@etagwerker, thanks for the feedback!

You're right, the other benchmarks are really just edge cases, and don't contribute much. And Hash#values_at is the best performing in them anyway.

I've removed the redundant benchmarks. How does it look now?

d: 'qux'
}.freeze

# Some of the keys may not exist in the hash; we want to keep the default values.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For existing keys, the benchmark does not change much.

# frozen_string_literal: true
require 'benchmark/ips'
HASH = {
 a: 'foo',
 b: 'bar',
 c: 'baz',
 d: 'qux'
}.freeze
# the keys exist in the hash
KEYS = %i[a b c d].freeze
def fastest
 HASH.values_at(*KEYS)
end
def slow
 HASH.fetch_values(*KEYS)
end
def slowest
 KEYS.map { |key| HASH[key] }
end
Benchmark.ips do |x|
 x.report('Hash#values_at ') { fastest }
 x.report('Hash#fetch_values ') { slow }
 x.report('Array#map { Hash#[] }') { slowest }
 x.compare!
end
ydakuka@yauhenid:~/ruby-docker-app$ docker run ruby-app 
Warming up --------------------------------------
Hash#values_at 
 405.669k i/100ms
Hash#fetch_values 
 354.263k i/100ms
Array#map { Hash#[] }
 221.960k i/100ms
Calculating -------------------------------------
Hash#values_at 
 4.191M (± 4.7%) i/s - 21.095M in 5.045130s
Hash#fetch_values 
 3.895M (± 6.8%) i/s - 19.484M in 5.031663s
Array#map { Hash#[] }
 2.429M (± 6.1%) i/s - 12.208M in 5.048470s
Comparison:
Hash#values_at : 4190993.6 i/s
Hash#fetch_values : 3894866.5 i/s - same-ish: difference falls within error
Array#map { Hash#[] }: 2429428.6 i/s - 1.73x slower

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

1 more reviewer

@ydakuka ydakuka ydakuka left review comments

Reviewers whose approvals may not affect merge requirements

Assignees

No one assigned

Labels

None yet

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

AltStyle によって変換されたページ (->オリジナル) /