Skip to content
Permalink
Browse files

Add ActiveSupport and faster implementation

  • Loading branch information...
styd committed Mar 9, 2019
1 parent 90750df commit 8d394e07ae4bd4135968100ade801fc4a3832e3a
Showing with 66 additions and 30 deletions.
  1. +17 −8 README.md
  2. +49 −0 code/hash/slice-native-vs-before-native.rb
  3. +0 −22 code/hash/slice-vs-select-include.rb
@@ -937,24 +937,33 @@ Comparison:
sort + to_h: 81972.8 i/s - 1.49x slower
```

##### `Hash#slice` vs `Hash#select{ includes? }` [code](code/hash/slice-vs-select-include.rb)
##### Native `Hash#slice` vs other slice implementations before native
[code](code/hash/slice-native-vs-before-native.rb)

Since ruby 2.5, Hash comes with a `slice` method to select hash members by keys.

```
$ ruby code/hash/slice-vs-select-include.rb
$ ruby -v code/hash/slice-native-vs-before-native.rb
ruby 2.5.3p105 (2018-10-18 revision 65156) [x86_64-linux]
Warming up --------------------------------------
Hash#native-slice 178.077k i/100ms
Array#each 124.311k i/100ms
Array#each_w/_object 110.818k i/100ms
Hash#select-include 66.972k i/100ms
Calculating -------------------------------------
Hash#slice 3.124M (± 0.6%) i/s - 15.675M in 5.017984s
Hash#select_if_includes
1.342M (± 1.1%) i/s - 6.716M in 5.003901s
Hash#native-slice 2.540M (± 1.5%) i/s - 12.822M in 5.049955s
Array#each 1.614M (± 1.0%) i/s - 8.080M in 5.007925s
Array#each_w/_object 1.353M (± 2.6%) i/s - 6.760M in 5.000441s
Hash#select-include 760.944k (± 0.9%) i/s - 3.817M in 5.017123s
Comparison:
Hash#slice: 3123803.2 i/s
Hash#select_if_includes: 1342270.6 i/s - 2.33x slower
Hash#native-slice : 2539515.5 i/s
Array#each : 1613665.5 i/s - 1.57x slower
Array#each_w/_object: 1352851.8 i/s - 1.88x slower
Hash#select-include : 760944.2 i/s - 3.34x slower
```


### Proc & Block

##### Block vs `Symbol#to_proc` [code](code/proc-and-block/block-vs-to_proc.rb)
@@ -0,0 +1,49 @@
require 'benchmark/ips'

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

HASH.dup.each{ |k, v| HASH[:"other_#{k}"], HASH[:"more_#{k}"] = v, v }

# Native implementation since v2.5
#
def fastest
HASH.slice(*%i[title author other])
end

# @ixti's faster implementation than that of ActiveSupport below
#
# Source:
# https://github.com/JuanitoFatas/fast-ruby/pull/173#issuecomment-470554483
#
def faster
memo = {}
%i[title author other].each { |k| memo[k] = HASH[k] if HASH.key?(k) }
memo
end

# ActiveSupport implementation of `slice` when it's not defined.
#
# Source:
# https://github.com/rails/rails/blob/01ae39660243bc5f0a986e20f9c9bff312b1b5f8/activesupport/lib/active_support/core_ext/hash/slice.rb#L24
#
def fast
%i[title author other].each_with_object({}){ |k, h| h[k] = HASH[k] if HASH.key?(k) }
end

def slow
keys = %i[title author other]
HASH.select { |k, _| keys.include? k }
end

Benchmark.ips do |x|
x.report('Hash#native-slice ') { fastest }
x.report('Array#each ') { faster }
x.report('Array#each_w/_object') { fast }
x.report('Hash#select-include ') { slow }
x.compare!
end

This file was deleted.

0 comments on commit 8d394e0

Please sign in to comment.
You can’t perform that action at this time.