jol*_*oft 5 .net c# performance for-loop enumerable
我想知道Enumerable.Range使用foreach循环的性能开销是什么。例如:
var stringArray = Enumerable.Range(0, 4).Select(i => string.Empty).ToArray();
Run Code Online (Sandbox Code Playgroud)
对比。
var stringArray = new string[4];
for (int i = 0; i < formatted.Length; i++)
{
stringArray[i] = string.Empty;
}
Run Code Online (Sandbox Code Playgroud)
我发现了这些问题:
但是我担心Select最后我可能会实际上循环两次。但是,我喜欢使用该Range选项的优雅。
从以下测试中,for效率更高:(以毫秒为单位是 +-3 毫秒的差异 - 这是微不足道的..)
var watch = System.Diagnostics.Stopwatch.StartNew();
var stringArra1y = Enumerable.Range(0, 4).Select(i => string.Empty).ToArray();
watch.Stop();
Console.WriteLine(watch.ElapsedTicks); //3305
watch = System.Diagnostics.Stopwatch.StartNew();
var stringArray2 = new string[4];
for (int i = 0; i < stringArray2.Length; i++)
{
stringArray2[i] = string.Empty;
}
watch.Stop();
Console.WriteLine(watch.ElapsedTicks); //1
Run Code Online (Sandbox Code Playgroud)
但是您可以代替使用Enumerable.Range().Selectuse .Repeat:
var watch = System.Diagnostics.Stopwatch.StartNew();
var stringArra1y = Enumerable.Repeat(string.Empty, 4).ToArray();
watch.Stop();
Console.WriteLine(watch.ElapsedTicks); //391
Run Code Online (Sandbox Code Playgroud)
说完上述注意,您在这里谈论的是非常小的集合(4 个项目)。在较大的集合中,特别是如果您删除.ToArray()它,它的行为就不一样了:
var watch = System.Diagnostics.Stopwatch.StartNew();
var stringArra1y = Enumerable.Repeat(string.Empty, 100000);
watch.Stop();
Console.WriteLine(watch.ElapsedTicks); //360
watch = System.Diagnostics.Stopwatch.StartNew();
var stringArray2 = new string[100000];
for (int i = 0; i < stringArray2.Length; i++)
{
stringArray2[i] = string.Empty;
}
watch.Stop();
Console.WriteLine(watch.ElapsedTicks); //1335
Run Code Online (Sandbox Code Playgroud)
但是我担心最后使用 Select 那么我实际上可能会循环两次
展望虽然参考源均.Range和Repeat与一个实现yield return:
static IEnumerable<int> RangeIterator(int start, int count) {
for (int i = 0; i < count; i++) yield return start + i;
}
Run Code Online (Sandbox Code Playgroud)
所以它也被延迟执行,就像.Select它不会循环两次的意思一样。
并不是Stopwatch每次运行都使用返回不同的结果,而是总体思路如上所示
IMO,尤其是在小集合的情况下,通过这些微小的性能改进来提高可读性。当您已经遇到性能问题时,只有在获得更大的鱼(例如使用嵌套for循环List<>而不是使用 a HashSet<>)之后,才能处理这样的事情。