知りたいと思った理由
今までソフト開発で配列を1度も使用したことがなくリストとの処理速度差が気になったため。
環境
- VisualStdio 2022
- .Net6
- C#10.0
- コンソールアプリケーション
結果
メモリ使用量(ソフト全体)[byte]
要素数 | リスト | 配列 | 差分(リスト-配列) |
---|---|---|---|
1,000 | 528,504[byte] | 529,280[byte] | -776[byte] |
100,000,000(1億) | 40,531,680[byte] | 40,530,792[byte] | 888[byte] |
2,147,483,591(21億) | 8,590,466,040[byte] | 8,590,466,080[byte] | -40[byte] |
Forでループした場合の時間[ms]
要素数 | リスト | 配列 | 差分(リスト-配列) |
---|---|---|---|
1,000 | 0[ms] | 0[ms] | 0[ms] |
100,000,000(1億) | 449[ms] | 180[ms] | 269[ms] |
2,147,483,591(21億) | 6616[ms] | 3823[ms] | 2793[ms] |
ForEachでループした場合の時間[ms]
要素数 | リスト | 配列 | 差分(リスト-配列) |
---|---|---|---|
1,000 | 0[ms] | 0[ms] | 0[ms] |
100,000,000(1億) | 396[ms] | 249[ms] | 147[ms] |
2,147,483,591(21億) | 6462[ms] | 3911[ms] | 2551[ms] |
個人的見解
これくらいの誤差であれば途中追加できるリスト
を使用した方がいいと思いました。たまにVB.NETのソースコードでReDimという配列の要素数を再定義しているソース(要素数は3個程度)を見るのですがそんなことするなら処理速度を捨ててソースの可読性を優先してリスト
を使うべきということが分かりました。要素数が固定されているものは配列
を使うといいとインターネットの記事を読むと書いてあるのですが、要素数が固定されているものというのは基本的に要素数が少ないので(星座(88種類)や血液型(4種類))リスト
でも別に問題ないかなと思いました。ただ、配列
は多次元配列を扱うことができるので多次元配列をどうしても使用しなければならない場合は配列
を使用してもいいのかなと思いました。(多次元配列は複雑化してソースが読みにくいので極力使わないのがいいと思います。)
使用したソースコード
配列の検証ソース
配列の検証ソース
using System.Diagnostics;
var arrayTestData = Enumerable.Range(0, 2_147_483_591).ToArray();
long currentSet = GC.GetTotalMemory(true);
Console.WriteLine($"Listの場合。要素数:{arrayTestData.Length}。メモリ使用量(ソフトの合計使用量){currentSet:N0}[byte]");
var sw = new Stopwatch();
sw.Restart();
for (int i = 0; i < arrayTestData.Length - 1; i++)
{
var _ = arrayTestData[i];
}
sw.Stop();
Console.WriteLine($"Forでループ。要素数:{arrayTestData.Length}。実行時間:{sw.ElapsedMilliseconds}[ms]");
sw.Restart();
foreach (var testData in arrayTestData)
{
var _ = testData;
}
sw.Stop();
Console.WriteLine($"ForEachでループ。要素数:{arrayTestData.Length}。実行時間:{sw.ElapsedMilliseconds}[ms]");
リストの検証ソース
リストの検証ソース
using System.Diagnostics;
var listTestData = Enumerable.Range(0, 2_147_483_591).ToList();
long currentSet = GC.GetTotalMemory(true);
Console.WriteLine($"Listの場合。要素数:{listTestData.Count}。メモリ使用量(ソフトの合計使用量){currentSet:N0}[byte]");
var sw = new Stopwatch();
sw.Restart();
for (int i = 0; i < listTestData.Count - 1; i++)
{
var _ = listTestData[i];
}
sw.Stop();
Console.WriteLine($"Forでループ。要素数:{listTestData.Count}。実行時間:{sw.ElapsedMilliseconds}[ms]");
sw.Restart();
foreach (var testData in listTestData)
{
var _ = testData;
}
sw.Stop();
Console.WriteLine($"ForEachでループ。要素数:{listTestData.Count}。実行時間:{sw.ElapsedMilliseconds}[ms]");