Rubyで文字列のタイム表示を昇順に並び替える

## やりたいこと
文字列のタイム表示を昇順で並び替える。

条件

- 文字列の形式は`00:00.00` (分 : 秒 . 小数点以下2ケタ)
- 想定のタイム範囲は`05:00.00`から`10:59.99`
- 件数はおよそ250件

## 環境
- Ruby 3.1.0p0
- macOS 10.15.7

## 文字列のサンプルをつくる
`Integer#times`、`Kernel.#rand`、`Time#local`、`Time#strftime`を使って250件のサンプルをつくった。

```ruby
array = []
250.times { array << rand(Time.local(2022,3,14,1,5,0,0,0)..Time.local(2022,3,14,1,10,59,999) ) }

#Timeオブジェクトを`Time#strftime`を使って文字列に成形する
samples = array.map{|t| t.strftime("%M:%S.%2N")}
#=> ["10:11.12", "05:30.87", "09:59.53", "08:25.66", "07:57.37",...... "08:28.48", "07:17.87", "09:24.65", "10:47.52", "05:21.44"]
```

## 並び替えのベンチマークテストをする
[2022-03-16]修正

処理内容や数量によって`sort`と`sort_by`のどちらが速いかが変わるようなので、Benchmarkモジュールのbm関数を使ってテストしてみる。

https://docs.ruby-lang.org/ja/latest/class/Benchmark.html

試したのは次の4つ。
- `sort_by`
  - 文字列からintegerに変換してからsort
  - 文字列のままsort
- `sort`
  - 文字列からintegerに変換してからsort
  - 文字列のままsort
 

```ruby
require 'benchmark'

#レポート名をつけて計測する
Benchmark.bm(10) do |x|
	x.report('sort_by_i') {samples.sort_by { |s| s.delete(":.").to_i } }
	x.report('sort_by_s') {samples.sort_by { |s| s } }
	x.report('sort_i')    {samples.sort { |a, b| a.delete(":.").to_i <=> b.delete(":.").to_i } }
	x.report('sort_s')    {samples.sort}
end
```

## 追記[2022-03-16]
@scivolaさんからコメントで色々と教えていただき`gem.benchmark_driver`でもテストを行ってみた。

その際、
`.delete(":").delete(".")`を`.delete(":.")`に
`samples.sort{|a,b| a <=> b}`を`samples.sort`に変更。

参考
benchmark-driver
https://github.com/benchmark-driver/benchmark-driver


https://qiita.com/k0kubun/items/82196240d3a7f987d1be



まず`benchmark_driver`をインストール。

```
$ gem install benchmark_driver
```

**code**

```Ruby
require 'benchmark_driver'

#テスト対象を文字列で記入
Benchmark.driver do |x|
	x.prelude <<~RUBY
		array = []
		250.times { array << rand(Time.local(2022,3,14,1,5,0,0,0)..Time.local(2022,3,14,1,10,59,999) ) }
		samples = array.map{|t| t.strftime("%M:%S.%2N")}
  RUBY
	x.report 'sort_by_i' , %{ samples.sort_by \{ |s| s.delete(":.").to_i \} }
	x.report 'sort_by_s' , %{ samples.sort_by \{ |s| s \} }
	x.report 'sort_i'    , %{ samples.sort \{ |a, b| a.delete(":.").to_i <=> b.delete(":.").to_i \} }
	x.report 'sort_s'    , %{ samples.sort }
end
```

## 結果
[2022-03-16]修正

**benchmarkモジュールの結果**

```
                 user     system      total        real
sort_by_i    0.000199   0.000005   0.000204 (  0.000191)
sort_by_s    0.000106   0.000000   0.000106 (  0.000106)
sort_i       0.002053   0.000006   0.002059 (  0.002049)
sort_s       0.000055   0.000001   0.000056 (  0.000055)
```

文字列のまま`sort`を使うのが速いもよう。

レポートの見方はこちらの記事を参考にしました。
https://qiita.com/scivola/items/c5b2aeaf7d67a9ef310a

ちゃんと昇順に並び替えられているか確認。

```ruby
p samples.sort

#=> ["05:00.13", "05:00.23", "05:00.56", "05:02.97", "05:03.29", ... "10:51.62", "10:54.19", "10:54.99", "10:55.26", "10:55.39"]
```

できてました。

ちなみにサンプル10件でテストした結果は以下。

```
#サンプル10件

                 user     system      total        real
sort_by_i    0.000021   0.000004   0.000025 (  0.000019)
sort_by_s    0.000006   0.000001   0.000007 (  0.000006)
sort_i       0.000042   0.000001   0.000043 (  0.000042)
sort_s       0.000003   0.000001   0.000004 (  0.000012)
```

やはり文字列のまま`sort`を使うのが速そうです。

**benchmark-driverの結果**

```
Warming up --------------------------------------
           sort_by_i     7.769k i/s -      8.426k times in 1.084521s (128.71μs/i)
           sort_by_s    12.458k i/s -     13.288k times in 1.066642s (80.27μs/i)
              sort_i    805.194 i/s -     810.000 times in 1.005969s (1.24ms/i)
              sort_s    25.315k i/s -     26.741k times in 1.056332s (39.50μs/i)
Calculating -------------------------------------
           sort_by_i     7.590k i/s -     23.307k times in 3.070740s (131.75μs/i)
           sort_by_s    12.333k i/s -     37.373k times in 3.030289s (81.08μs/i)
              sort_i    782.899 i/s -      2.415k times in 3.084688s (1.28ms/i)
              sort_s    25.393k i/s -     75.944k times in 2.990800s (39.38μs/i)

Comparison:
              sort_s:     25392.5 i/s 
           sort_by_s:     12333.1 i/s - 2.06x  slower
           sort_by_i:      7590.0 i/s - 3.35x  slower
              sort_i:       782.9 i/s - 32.43x  slower
```

こちらは1秒あたりの実行回数が出るようなので、数字が大きいほうが速いということになるらしい。
文字列のまま`sort`する方が文字列のまま`sort_by`するより2倍ほど速い結果になりました。

以上