SeqとListとArrayのパフォーマンス比較

##SeqとListとArrayのパフォーマンス比較
気になったので実験してみた。
単純な生成コストと、インデックスアクセスの速度を比較。

~~速度はSeq > Array >> Listのようである。~~
@vain0x さんにコメント欄で指摘いただいた通り、計測コードの書き方が間違ってたみたい。

再計測の結果、速度はArray >>> List > Seq となった。
※数は公平にするために10^8のまま

###dotnetcore2.1で計測

| Method |         Mean |       Error |      StdDev |       Median |
|------- |-------------:|------------:|------------:|-------------:|
| ABench(Seq) | 182,376.5 ns | 5,210.94 ns | 14,088.1 ns | 175,500.0 ns |
| BBench(List) | 214,139.7 ns | 5,123.56 ns | 12,759.4 ns | 214,900.0 ns |
| CBench(Array) |     766.0 ns |    68.92 ns |    199.9 ns |     800.0 ns |

###dotnetcore3.1で計測

| Method |       Mean |      Error |    StdDev |     Median |
|------- |-----------:|-----------:|----------:|-----------:|
| ABench(Seq) | 243.788 us | 14.0499 us | 41.206 us | 230.800 us |
| BBench(List) | 228.499 us |  5.4869 us | 15.743 us | 226.600 us |
| CBench(Array) |   2.068 us |  0.6108 us |  1.672 us |   1.300 us |

頂いたコメントとデータの傾向が違うなと思ってたら、dotnetのバージョンの差異のようだ。
3.1にするとだいたい近い結果になった。

サマリは単位がマイクロとナノでずれてるけど、
揃えて考えると2.1より3.1の方が全体的に遅くなってる感がある。

走行時間も増えてるし、なんでやろねぇ。

###感想
ベンチ走らせるのに約35分程かかった。
途中で気づいたけど、もっとまともなベンチ名にするべきだったね...

まあListはデータ構造的にアクセス速度遅くて当然として。

当初予想では、Seqはメモリ上一個しか存在しないらしいと聞いて
Arrayよりも生成コストかからず爆速になるのかなーって思ってた。

Arrayだとインスタンス2個とも100,000,000回ループ回すけど
Seqはインスタンス1個分だけ生成したら、2個目にはインスタンス1のアドレスが代入されるのかなーと。
内包表記を2個呼び出してるのはこれを試そうと思ったから。
実際見てるとリストよりも遅いので、そんなに早い訳ではないらしい。

##検証コードと結果
###テストコード(修正版)
```fsharp:テストコード
module Program

open BenchmarkDotNet
open BenchmarkDotNet.Attributes

let buildCardSeq = seq { 1..100000000 }
let buildCardList = [ 1..100000000 ]
let buildCardArray = [| 1..100000000 |]

let A () =
    let bs1 = buildCardSeq
    let bs2 = buildCardSeq
    bs1 |> Seq.item 56789

let B () =
    let bl1 = buildCardList
    let bl2 = buildCardList
    bl1 |> List.item 56789

let C () =
    let ba1 = buildCardArray
    let ba2 = buildCardArray
    ba1 |> Array.item 56789

type Benchmarks() =
    [<Benchmark>]
    member x.ABench() =
        A()

    [<Benchmark>]
    member x.BBench() =
        B()

    [<Benchmark>]
    member x.CBench() =
        C()

[<EntryPoint>]
let main _ =
    let _summary = Running.BenchmarkRunner.Run<Benchmarks>()
    0
```

###サマリ(dotnetcore3.1)
```
// * Summary *

BenchmarkDotNet=v0.12.0, OS=Windows 10.0.18363
Intel Core i7-4650U CPU 1.70GHz (Haswell), 1 CPU, 4 logical and 2 physical cores
.NET Core SDK=3.1.101
  [Host]     : .NET Core 3.1.1 (CoreCLR 4.700.19.60701, CoreFX 4.700.19.60801), X64 RyuJIT DEBUG
  DefaultJob : .NET Core 3.1.1 (CoreCLR 4.700.19.60701, CoreFX 4.700.19.60801), X64 RyuJIT


| Method |       Mean |      Error |    StdDev |     Median |
|------- |-----------:|-----------:|----------:|-----------:|
| ABench | 243.788 us | 14.0499 us | 41.206 us | 230.800 us |
| BBench | 228.499 us |  5.4869 us | 15.743 us | 226.600 us |
| CBench |   2.068 us |  0.6108 us |  1.672 us |   1.300 us |

// * Warnings *
MinIterationTime
  Benchmarks.ABench: Default -> The minimum observed iteration time is 200.2000 us which is very small. It's recommended to increase it.
  Benchmarks.BBench: Default -> The minimum observed iteration time is 200.9000 us which is very small. It's recommended to increase it.
  Benchmarks.CBench: Default -> The minimum observed iteration time is 900.0000 ns which is very small. It's recommended to increase it.
MultimodalDistribution
  Benchmarks.BBench: Default -> It seems that the distribution can have several modes (mValue = 2.86)

// * Hints *
Outliers
  Benchmarks.ABench: Default -> 1 outlier  was  removed (405.80 us)
  Benchmarks.BBench: Default -> 5 outliers were removed (289.60 us..393.00 us)
  Benchmarks.CBench: Default -> 13 outliers were removed (7.20 us..11.80 us)

// * Legends *
  Mean   : Arithmetic mean of all measurements
  Error  : Half of 99.9% confidence interval
  StdDev : Standard deviation of all measurements
  Median : Value separating the higher half of all measurements (50th percentile)
  1 us   : 1 Microsecond (0.000001 sec)

// ***** BenchmarkRunner: End *****
// ** Remained 0 benchmark(s) to run **
Run time: 00:37:52 (2272.5 sec), executed benchmarks: 3

Global total time: 00:37:58 (2278.54 sec), executed benchmarks: 3
// * Artifacts cleanup *
```

###サマリ(dotnetcore2.1)
```
// * Summary *

BenchmarkDotNet=v0.12.0, OS=Windows 10.0.18363
Intel Core i7-4650U CPU 1.70GHz (Haswell), 1 CPU, 4 logical and 2 physical cores
.NET Core SDK=3.1.101
  [Host]     : .NET Core 2.1.9 (CoreCLR 4.6.27414.06, CoreFX 4.6.27415.01), X64 RyuJIT DEBUG
  DefaultJob : .NET Core 2.1.9 (CoreCLR 4.6.27414.06, CoreFX 4.6.27415.01), X64 RyuJIT


| Method |         Mean |       Error |      StdDev |       Median |
|------- |-------------:|------------:|------------:|-------------:|
| ABench | 182,376.5 ns | 5,210.94 ns | 14,088.1 ns | 175,500.0 ns |
| BBench | 214,139.7 ns | 5,123.56 ns | 12,759.4 ns | 214,900.0 ns |
| CBench |     766.0 ns |    68.92 ns |    199.9 ns |     800.0 ns |

// * Warnings *
MinIterationTime
  Benchmarks.ABench: Default -> The minimum observed iteration time is 175.1000 us which is very small. It's recommended to increase it.
  Benchmarks.BBench: Default -> The minimum observed iteration time is 192.3000 us which is very small. It's recommended to increase it.
  Benchmarks.CBench: Default -> The minimum observed iteration time is 400.0000 ns which is very small. It's recommended to increase it.
MultimodalDistribution
  Benchmarks.BBench: Default -> It seems that the distribution can have several modes (mValue = 3.03)

// * Hints *
Outliers
  Benchmarks.ABench: Default -> 15 outliers were removed (245.20 us..340.60 us)
  Benchmarks.BBench: Default -> 12 outliers were removed (258.70 us..370.60 us)
  Benchmarks.CBench: Default -> 3 outliers were removed (1.60 us..2.10 us)

// * Legends *
  Mean   : Arithmetic mean of all measurements
  Error  : Half of 99.9% confidence interval
  StdDev : Standard deviation of all measurements
  Median : Value separating the higher half of all measurements (50th percentile)
  1 ns   : 1 Nanosecond (0.000000001 sec)

// ***** BenchmarkRunner: End *****
// ** Remained 0 benchmark(s) to run **
Run time: 00:34:56 (2096.23 sec), executed benchmarks: 3

Global total time: 00:35:05 (2105.93 sec), executed benchmarks: 3
// * Artifacts cleanup *
```
##修正前
今後の自分のために残しておく

###テストコード(修正前)
```fsharp:テストコード

module Program

open BenchmarkDotNet
open BenchmarkDotNet.Attributes

let buildCardSeq = seq { 1..100000000 }
let buildCardList = [ 1..100000000 ]
let buildCardArray = [| 1..100000000 |]

let A =
    let bs1 = buildCardSeq
    let bs2 = buildCardSeq
    bs1 |> Seq.item 56789

let B =
    let bl1 = buildCardList
    let bl2 = buildCardList
    bl1 |> List.item 56789

let C =
    let ba1 = buildCardArray
    let ba2 = buildCardArray
    ba1 |> Array.item 56789

type Benchmarks() =
    [<Benchmark>]
    member x.ABench() =
        A

    [<Benchmark>]
    member x.BBench() =
        B

    [<Benchmark>]
    member x.CBench() =
        C

[<EntryPoint>]
let main _ =
    let _summary = Running.BenchmarkRunner.Run<Benchmarks>()
    0
```

###サマリ(修正前)
```txt
// * Summary *

BenchmarkDotNet=v0.12.0, OS=Windows 10.0.18363
Intel Core i7-4650U CPU 1.70GHz (Haswell), 1 CPU, 4 logical and 2 physical cores
.NET Core SDK=3.1.101
  [Host]     : .NET Core 2.1.9 (CoreCLR 4.6.27414.06, CoreFX 4.6.27415.01), X64 RyuJIT DEBUG
  DefaultJob : .NET Core 2.1.9 (CoreCLR 4.6.27414.06, CoreFX 4.6.27415.01), X64 RyuJIT


| Method |         Mean |       Error |      StdDev |       Median |
|------- |-------------:|------------:|------------:|-------------:|
| ABench | 182,376.5 ns | 5,210.94 ns | 14,088.1 ns | 175,500.0 ns |
| BBench | 214,139.7 ns | 5,123.56 ns | 12,759.4 ns | 214,900.0 ns |
| CBench |     766.0 ns |    68.92 ns |    199.9 ns |     800.0 ns |

// * Warnings *
MinIterationTime
  Benchmarks.ABench: Default -> The minimum observed iteration time is 175.1000 us which is very small. It's recommended to increase it.
  Benchmarks.BBench: Default -> The minimum observed iteration time is 192.3000 us which is very small. It's recommended to increase it.
  Benchmarks.CBench: Default -> The minimum observed iteration time is 400.0000 ns which is very small. It's recommended to increase it.
MultimodalDistribution
  Benchmarks.BBench: Default -> It seems that the distribution can have several modes (mValue = 3.03)

// * Hints *
Outliers
  Benchmarks.ABench: Default -> 15 outliers were removed (245.20 us..340.60 us)
  Benchmarks.BBench: Default -> 12 outliers were removed (258.70 us..370.60 us)
  Benchmarks.CBench: Default -> 3 outliers were removed (1.60 us..2.10 us)

// * Legends *
  Mean   : Arithmetic mean of all measurements
  Error  : Half of 99.9% confidence interval
  StdDev : Standard deviation of all measurements
  Median : Value separating the higher half of all measurements (50th percentile)
  1 ns   : 1 Nanosecond (0.000000001 sec)

// ***** BenchmarkRunner: End *****
// ** Remained 0 benchmark(s) to run **
Run time: 00:34:56 (2096.23 sec), executed benchmarks: 3

Global total time: 00:35:05 (2105.93 sec), executed benchmarks: 3
// * Artifacts cleanup *
```