我想知道使用Enumerable.Range
对使用foreach
循环的性能开销是多少。例如:
var stringArray = Enumerable.Range(0, 4).Select(i => string.Empty).ToArray();
VS
var stringArray = new string[4];
for (int i = 0; i < formatted.Length; i++)
{
stringArray[i] = string.Empty;
}
我发现了这些问题:
Thoughts on foreach with Enumerable.Range vs traditional for loop
但是我最后担心Select
然后我可能会循环两次。但是我喜欢使用Range
选项的优雅。
答案 0 :(得分:4)
从下面的测试中,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
但您可以使用Enumerable.Range().Select
而不是.Repeat
使用var watch = System.Diagnostics.Stopwatch.StartNew();
var stringArra1y = Enumerable.Repeat(string.Empty, 4).ToArray();
watch.Stop();
Console.WriteLine(watch.ElapsedTicks); //391
:
.ToArray()
在说完上面的通知后,你在这里谈论非常小的收藏品(4项)。在较大的集合中,尤其是如果删除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
,它的行为不相同:
.Range
但是我担心最后选择Select,实际上我可能会循环两次
尽管Repeat
和yield return
的{{3}}都是通过static IEnumerable<int> RangeIterator(int start, int count) {
for (int i = 0; i < count; i++) yield return start + i;
}
来实现的:
.Select
所以它也被id执行了,就像Stopwatch
意味着它不会循环两次。
并非使用for
每次运行会返回不同的结果,但整体构思如上所示
IMO ,特别是在小型集合的情况下,为了提高可读性而进行了较小的性能改进。当你遇到性能问题时,只有在获得更大的鱼(例如List<>
上的嵌套HashSet<>
循环而不是使用/var/www
)之后,才能处理这样的事情。
答案 1 :(得分:1)
在我非常简单的测试中,看起来对于1 000 000个字符串,循环速度提高了38ms。
static void Main(string[] args)
{
var start = DateTime.Now;
EnTest();
var end = DateTime.Now;
var firstResult = end - start;
Console.WriteLine("Difference for Enumerable: {0}ms", firstResult.Milliseconds);
GC.Collect();
Thread.Sleep(2000);
var secondStart = DateTime.Now;
ArTest();
var secondEnd = DateTime.Now;
var secondResult = secondEnd - secondStart;
Console.WriteLine("Difference for loop: {0}ms", secondResult.Milliseconds);
var globalResult = firstResult - secondResult;
Console.WriteLine("Difference between tests: {0}ms", globalResult.Milliseconds);
Console.ReadKey();
}
public static void EnTest()
{
var stringArray = Enumerable.Range(0, 1000000).Select(i => string.Empty).ToArray();
}
public static void ArTest()
{
var stringArray = new string[1000000];
for (int i = 0; i < stringArray.Length; i++)
{
stringArray[i] = string.Empty;
}
}