Skip to content
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

Cop idea: Native Hash#slice vs other slice implementations before native code #394

Open
ydakuka opened this issue Nov 25, 2023 · 2 comments

Comments

@ydakuka
Copy link
Contributor

ydakuka commented Nov 25, 2023

https://github.com/fastruby/fast-ruby#native-hashslice-vs-other-slice-implementations-before-native-code

Describe the solution you'd like

HASH = {
  title: "awesome",
  description: "a description",
  author: "styd",
  published_at: Time.now
}

KEYS = %i[title author other].freeze

# bad
def my_method
  HASH.select { |k, _| KEYS.include? k }
end

# bad
def my_method
  memo = {}
  KEYS.each { |k| memo[k] = HASH[k] if HASH.key?(k) }
  memo
end

# bad
def my_method
  KEYS.each_with_object({}){ |k, h| h[k] = HASH[k] if HASH.key?(k) }
end

# good
def my_method
  HASH.slice(*KEYS)
end

Rubocop

ydakuka@yauhenid:~/Work/project$ bin/rails_docker rubocop -V
1.57.2 (using Parser 3.2.2.4, rubocop-ast 1.29.0, running on ruby 2.7.8) [x86_64-linux]
  - rubocop-capybara 2.19.0
  - rubocop-factory_bot 2.24.0
  - rubocop-performance 1.19.1
  - rubocop-rails 2.22.0
  - rubocop-rake 0.6.0
  - rubocop-rspec 2.25.0
  - rubocop-thread_safety 0.5.1
@ydakuka
Copy link
Contributor Author

ydakuka commented Nov 25, 2023

I've benchmarked it (ruby 3.3.0).

ydakuka@yauhenid:~/ruby-docker-app$ docker run ruby-app  
ruby 3.3.0 (2023-12-25 revision 5124f9ac75) [x86_64-linux]
Warming up --------------------------------------
Hash#native-slice      342.197k i/100ms
Array#each             180.535k i/100ms
Array#each_w/_object   115.737k i/100ms
Hash#select-include     56.865k i/100ms
Calculating -------------------------------------
Hash#native-slice         3.588M (± 1.5%) i/s -     18.136M in   5.056031s
Array#each                1.681M (± 1.1%) i/s -      8.485M in   5.048040s
Array#each_w/_object      1.336M (± 4.9%) i/s -      6.713M in   5.041132s
Hash#select-include     540.935k (± 4.7%) i/s -      2.730M in   5.057020s

Comparison:
Hash#native-slice   :  3587866.5 i/s
Array#each          :  1681076.6 i/s - 2.13x  slower
Array#each_w/_object:  1335545.9 i/s - 2.69x  slower
Hash#select-include :   540935.0 i/s - 6.63x  slower

@ydakuka
Copy link
Contributor Author

ydakuka commented Nov 25, 2023

I've dug into the real-world- repos and found that the pattern (Hash#select-include) is pretty popular.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant