Skip to content

Commit 9ac23c8

Browse files
authored
Merge pull request #173 from styd/hash-slice
Native Hash#slice vs other slice alternatives
2 parents 013fa34 + 8d394e0 commit 9ac23c8

File tree

2 files changed

+76
-0
lines changed

2 files changed

+76
-0
lines changed

README.md

+27
Original file line numberDiff line numberDiff line change
@@ -937,6 +937,33 @@ Comparison:
937937
sort + to_h: 81972.8 i/s - 1.49x slower
938938
```
939939

940+
##### Native `Hash#slice` vs other slice implementations before native
941+
[code](code/hash/slice-native-vs-before-native.rb)
942+
943+
Since ruby 2.5, Hash comes with a `slice` method to select hash members by keys.
944+
945+
```
946+
$ ruby -v code/hash/slice-native-vs-before-native.rb
947+
ruby 2.5.3p105 (2018-10-18 revision 65156) [x86_64-linux]
948+
Warming up --------------------------------------
949+
Hash#native-slice 178.077k i/100ms
950+
Array#each 124.311k i/100ms
951+
Array#each_w/_object 110.818k i/100ms
952+
Hash#select-include 66.972k i/100ms
953+
Calculating -------------------------------------
954+
Hash#native-slice 2.540M (± 1.5%) i/s - 12.822M in 5.049955s
955+
Array#each 1.614M (± 1.0%) i/s - 8.080M in 5.007925s
956+
Array#each_w/_object 1.353M (± 2.6%) i/s - 6.760M in 5.000441s
957+
Hash#select-include 760.944k (± 0.9%) i/s - 3.817M in 5.017123s
958+
959+
Comparison:
960+
Hash#native-slice : 2539515.5 i/s
961+
Array#each : 1613665.5 i/s - 1.57x slower
962+
Array#each_w/_object: 1352851.8 i/s - 1.88x slower
963+
Hash#select-include : 760944.2 i/s - 3.34x slower
964+
```
965+
966+
940967
### Proc & Block
941968

942969
##### Block vs `Symbol#to_proc` [code](code/proc-and-block/block-vs-to_proc.rb)
+49
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
require 'benchmark/ips'
2+
3+
HASH = {
4+
title: "awesome",
5+
description: "a description",
6+
author: "styd",
7+
published_at: Time.now
8+
}
9+
10+
HASH.dup.each{ |k, v| HASH[:"other_#{k}"], HASH[:"more_#{k}"] = v, v }
11+
12+
# Native implementation since v2.5
13+
#
14+
def fastest
15+
HASH.slice(*%i[title author other])
16+
end
17+
18+
# @ixti's faster implementation than that of ActiveSupport below
19+
#
20+
# Source:
21+
# https://github.com/JuanitoFatas/fast-ruby/pull/173#issuecomment-470554483
22+
#
23+
def faster
24+
memo = {}
25+
%i[title author other].each { |k| memo[k] = HASH[k] if HASH.key?(k) }
26+
memo
27+
end
28+
29+
# ActiveSupport implementation of `slice` when it's not defined.
30+
#
31+
# Source:
32+
# https://github.com/rails/rails/blob/01ae39660243bc5f0a986e20f9c9bff312b1b5f8/activesupport/lib/active_support/core_ext/hash/slice.rb#L24
33+
#
34+
def fast
35+
%i[title author other].each_with_object({}){ |k, h| h[k] = HASH[k] if HASH.key?(k) }
36+
end
37+
38+
def slow
39+
keys = %i[title author other]
40+
HASH.select { |k, _| keys.include? k }
41+
end
42+
43+
Benchmark.ips do |x|
44+
x.report('Hash#native-slice ') { fastest }
45+
x.report('Array#each ') { faster }
46+
x.report('Array#each_w/_object') { fast }
47+
x.report('Hash#select-include ') { slow }
48+
x.compare!
49+
end

0 commit comments

Comments
 (0)