LoginSignup
1
1

More than 5 years have passed since last update.

Ruby|配列をどう変換するか

Last updated at Posted at 2018-03-22

retryableというgemがあります。
キーワード引数matchingを使って捕捉する例外を指定することができます。

def retryable(tries:, matching: StandardError)
  begin
    # なんらかのテクニックが必要
  rescue *matching => e # このままでは動かない
    puts e.message
  end
end

ここで話題にしたいのはmatchingには例外クラスを配列で指定するか、
例外クラスを1つだけのどちらでも使えるようにするテクニックです。

rescueで例外を捕捉する必要がありますので1次元配列(入れ子でない)にする必要があります。
私がおもいついたのは3つです。retryableではflattenを利用しているようです。

matching = matching.is_a?(Array) ? matching : [matching]
matching = [matching].flatten
matching = Array[*matching]

これらのベンチマークを取ってみました。

require 'benchmark_driver'

Benchmark.driver do |x|
  x.prelude %{ array = [*1..5000] }
  x.report "flatten", %{ [array].flatten }
  x.report "using Array.[]", %{ Array[*array] }
  x.report "Object#is_a?", %{ array.is_a?(Array) ? array : [array] }
  x.compare!
end

なんと結果はflattenが一番遅いことがわかりました:sweat_smile:

Warming up --------------------------------------
             flatten     1.869k i/s
      using Array.[]    56.587k i/s
        Object#is_a?    16.534M i/s
Calculating -------------------------------------
             flatten     2.029k i/s -      5.607k times in 2.763675s (492.90μs/i)
      using Array.[]    54.798k i/s -    169.760k times in 3.097910s (18.25μs/i)
        Object#is_a?    30.039M i/s -     49.602M times in 1.651260s (33.29ns/i)

Comparison:
        Object#is_a?:  30038651.1 i/s 
      using Array.[]:     54798.2 i/s - 548.17x  slower
             flatten:      2028.8 i/s - 14805.97x  slower

ということでPRを本家に出しました:tada:
マージされるといいなぁ:smile:

1
1
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1