Hashのvalue側がarrayで全部取り出したいときの速度比較

# TL;DR
value側が

- 深さ1
  スピードは `each_value` が最速
  メソッドチェーン続けたい感じだったら `flat_map` も考えられる

- 深さ２以上で全部flatにしたいとき
  `values.flatten` が早いけど `each_value + flatten` とあまり速さ変わらないので好み。

実行環境 Ruby 2.7.1

# パターン
```ruby
sample = { a: [1, 2, 3], b: [2, 3, 4], c: [3, 4, 5] }
```


## 1. each
```ruby
ary = []
sample.each { |_k, v| ary.concat(v) }
ary
# =>  [1, 2, 3, 2, 3, 4, 3, 4, 5]
```

## 2. each_value
```ruby
ary = []
sample.each_value { |v| ary.push(*v) } # 上の例もconcatじゃなくてpushでも大丈夫
ary
# =>  [1, 2, 3, 2, 3, 4, 3, 4, 5]
```

## 3. values + flatten
```ruby
sample.values.flatten
# =>  [1, 2, 3, 2, 3, 4, 3, 4, 5]
```

## 4. flat_map
```ruby
# ruby 2.7だったら
sample.flat_map { _2 }
# =>  [1, 2, 3, 2, 3, 4, 3, 4, 5]

# _2が使えないなら
sample.flat_map { |_, v| v }
# =>  [1, 2, 3, 2, 3, 4, 3, 4, 5]

# flat_mapのレシーバーのvalueが何なのかココで示したいときはあえて書くのもありかなと思う
sample.flat_map { |_, number_ary| number_ary }
# =>  [1, 2, 3, 2, 3, 4, 3, 4, 5]
```

# テスト

## テスト1

深さ1のvalueをflatなArrayで取り出したいとき

結果は以下のとおりです。(1秒間に何回ループを回せるかという数字なので、デカイほうが早いです)

```
Comparison:
          each_value:  2859228.9 i/s
         each concat:  2745728.9 i/s - same-ish: difference falls within error
       flat_map(_,v):  1986117.7 i/s - 1.44x  (± 0.00) slower
        flat_map(_2):  1971975.8 i/s - 1.45x  (± 0.00) slower
      values flatten:   918971.6 i/s - 3.11x  (± 0.00) slower

```

<details><summary>テストコード</summary><div>

```ruby
require 'benchmark/ips'

sample = { a: [1, 2, 3], b: [2, 3, 4], c: [3, 4, 5] }

def method_1(h)
  ary = []
  h.each { |_k, v| ary.concat(v) }
  ary
end

def method_2(h)
  ary = []
  h.each_value { |v| ary.push(*v) }
  ary
end

def method_3(h)
  h.values.flatten
end

def method_4(h)
  h.flat_map { _2 }
end

def method_5(h)
  h.flat_map { |_, v| v }
end


Benchmark.ips do |x|
  x.config(:time => 20, :warmup => 2)

  x.report("each concat") { method_1(sample) }
  x.report("each_value ") { method_2(sample) }
  x.report("values flatten") { method_3(sample) }
  x.report("flat_map(_2)") { method_4(sample) }
  x.report("flat_map(_,v)") { method_5(sample) }

  x.compare!
end
```
</div></details>


## テスト2
深さ2の値で全部flatにして取り出したいとき

```
Comparison:
       values flatten:   800647.1 i/s
   each_value.flatten:   759526.1 i/s - 1.05x  (± 0.00) slower
     flat_map flatten:   676500.5 i/s - 1.18x  (± 0.00) slower
each_value in flatten:   468859.1 i/s - 1.71x  (± 0.00) slower
```

<details><summary>テストコード</summary><div>

```ruby
require 'benchmark/ips'

sample = { a: [1, 2, [3]], b: [2, 3, [4]], c: [3, 4, [5]] }

def method_1(h)
  ary = []
  h.each_value { |v| ary.push(*v.flatten) }
  ary
end

def method_2(h)
  ary = []
  h.each_value { |v| ary.push(*v) }
  ary.flatten
end

def method_3(h)
  h.values.flatten
end

def method_4(h)
  h.flat_map { _2 }.flatten
end


Benchmark.ips do |x|
  x.config(:time => 20, :warmup => 2)

  x.report("each_value in flatten") { method_1(sample) }
  x.report("each_value.flatten") { method_2(sample) }
  x.report("values flatten") { method_3(sample) }
  x.report("flat_map flatten") { method_4(sample) }

  x.compare!
end
```
</div></details>


# 結論
## 深さ1のとき  
each_valueでやるとのが一番早い。(eachを使うのとあまり変わらないが、可読性考えても普通にeach_valueか)
flat_mapだと返り値が欲しい値になっててメソッドチェーン続けやすいが遅め
values.flattenはかなり遅くなる

## 深さ２以上で全部flatにしたいとき
`values.flatten` が早いけど `each_value + flatten` と同じようなもん。

実行環境 Ruby 2.7.1