C# (dotnetcore) yield returnイテレーターは使った方が良いのか?
Mac Book Prodの dotnetcore3.1 で確認しました。
結論
結論からいうと、yield returnイテレーターを利用すると、メモリが節約され、若干時間が早くなった。
今回、指定したフォルダ配下のファイルを抽出する関数を、
List
List
IEnumerableでyield returnするパターンの関数
static IEnumerable<string> fileList(string path) { foreach (var f in System.IO.Directory.GetFiles(path)) { yield return f; } foreach (string dir in System.IO.Directory.GetDirectories(path)) { foreach (var f in fileList(dir)) { yield return f; } } }
Listに溜めて返却するパターンの関数
static List<string> fileList2(string path) { List<string> result = new List<string>(); result.AddRange(System.IO.Directory.GetFiles(path)); foreach (string dir in System.IO.Directory.GetDirectories(path)) { result.AddRange(fileList2(dir)); } return result; }
呼び出し側のソース
static void Main(string[] args) { for(int i = 0;i<10; i++) { System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch(); sw.Start(); int count = 0; foreach (string path in fileList2("/Applications/Visual Studio.app/")) { //Console.WriteLine(path); count++; } sw.Stop(); Console.WriteLine("ファイル数:{0:#,0}", count); Console.WriteLine("利用メモリ:{0:#,0}", Environment.WorkingSet); Console.WriteLine("実行時間:{0:#,0} ms", sw.ElapsedMilliseconds); } }
fileList2か、fileListと呼び出しを分けてそれぞれ確認しました。
計測結果
IEnumerable パターン
ファイル数:13,980 利用メモリ:21,479,424 実行時間:140 ms
ファイル数:13,980 利用メモリ:22,523,904 実行時間:120 ms
ファイル数:13,980 利用メモリ:26,517,504 実行時間:124 ms
ファイル数:13,980 利用メモリ:23,904,256 実行時間:108 ms
ファイル数:13,980 利用メモリ:26,537,984 実行時間:109 ms
ファイル数:13,980 利用メモリ:21,397,504 実行時間:104 ms
ファイル数:13,980 利用メモリ:21,639,168 実行時間:105 ms
ファイル数:13,980 利用メモリ:23,719,936 実行時間:109 ms
ファイル数:13,980 利用メモリ:22,876,160 実行時間:118 ms
ファイル数:13,980 利用メモリ:23,158,784 実行時間:109 ms
実行時間平均:114.6 ms 利用メモリ平均:23,375,462.4
Listに溜めて返却するパターン
ファイル数:13,980 利用メモリ:28,090,368 実行時間:145 ms
ファイル数:13,980 利用メモリ:35,373,056 実行時間:127 ms
ファイル数:13,980 利用メモリ:40,423,424 実行時間:112 ms
ファイル数:13,980 利用メモリ:49,569,792 実行時間:112 ms
ファイル数:13,980 利用メモリ:58,970,112 実行時間:108 ms
ファイル数:13,980 利用メモリ:60,899,328 実行時間:126 ms
ファイル数:13,980 利用メモリ:64,606,208 実行時間:106 ms
ファイル数:13,980 利用メモリ:55,943,168 実行時間:124 ms
ファイル数:13,980 利用メモリ:42,098,688 実行時間:106 ms
ファイル数:13,980 利用メモリ:47,419,392 実行時間:109 ms
実行時間平均:117.5 ms 利用メモリ平均:48,339,353.6