Skip to content

Compare Hash#select#values vs Hash#values#select vs Hash#values#compact - #124

Closed
sFrenkie wants to merge 1 commit into
fastruby:mainfrom
sFrenkie:master
Closed

sFrenkie wants to merge 1 commit into
fastruby:mainfrom
sFrenkie:master

Conversation

@sFrenkie

@sFrenkie sFrenkie commented May 5, 2017

Copy link
Copy Markdown
Contributor

This benchmark proves that get not nil values from hash is fastest with Hash#values#compact

@etagwerker etagwerker left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think this PR adds value if you keep the fastest and fast methods, but I feel like slow is doing something way different.

fast and fastest are calling a method on Array (compact vs select) but slow is calling a method on Hash and it's a little too contrived.

@etagwerker

Copy link
Copy Markdown
Member

Thanks for this, @sFrenkie! The core idea is useful, so I've opened #236 which builds on it.

One thing to flag: in this version the three expressions aren't quite equivalent. The test data uses boolean values (v < 0.5 → true/false) and contains no nil values, so Hash#values.compact filters nothing while the two select variants also drop false. That makes compact look fastest partly because it's doing less work.

#236 uses data that actually contains nil values so all three return the same result (plus an equivalence guard), and adds the README entry. The conclusion still holds: Hash#values.compact is the fastest way to get non-nil values. Closing this in favor of #236 — thanks again for the contribution!

@etagwerker etagwerker closed this Jun 28, 2026
JuanVqz added a commit that referenced this pull request Sep 29, 2026
…124)

From #236 by @etagwerker, which revisits #124 by @sFrenkie and fixes its
data (it had no nil values, so compact did less work): three ways to
collect the non-nil values of a hash. values.compact is the fast one.

Changes to the PR's file:
- The data no longer uses Random.rand, so the number of nils does not
  change from run to run: every other value is nil (500 of 1000).
- The two select reports keep values with !v.nil? instead of by
  truthiness, so like compact they drop only nil and keep false (from the
  PR's Copilot review). The two snippets in the README text change the
  same way.
- Rank-named methods: fast values.compact, slow values.select, slower
  select.values, the order on every CRuby and JRuby run.
- The sanity check compares the results as they are, without sorting,
  since all three keep the hash's order (from the PR's Copilot review).
- Single quotes, as RuboCop asks.

The README entry keeps the PR's ruby_4.0.0 sample, which ran the
truthiness version, and adds one from ruby_4.0.7 on the current code
(21.05x).

Co-authored-by: Ernesto Tagwerker <17584+etagwerker@users.noreply.github.com>
Co-authored-by: sFrenkie <20856072+sFrenkie@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants