C#、For 循环和速度测试……完全相同的循环第二次更快?

标签 c# arrays foreach for-loop loops

public Int64 ReturnDifferenceA()
{
  User[] arrayList;
  Int64 firstTicks;
  IList<User> userList;
  Int64 secondTicks;
  System.Diagnostics.Stopwatch watch;

  userList = Enumerable
              .Range(0, 1000)
              .Select(currentItem => new User()).ToList();

  arrayList = userList.ToArray();

  watch = new Stopwatch();
  watch.Start();

  for (Int32 loopCounter = 0; loopCounter < arrayList.Count(); loopCounter++)
  {
     DoThings(arrayList[loopCounter]);
  }

  watch.Stop();
  firstTicks = watch.ElapsedTicks;

  watch.Reset();
  watch.Start();
  for (Int32 loopCounter = 0; loopCounter < arrayList.Count(); loopCounter++)
  {
     DoThings(arrayList[loopCounter]);
  }
  watch.Stop();
  secondTicks = watch.ElapsedTicks;

  return firstTicks - secondTicks;
}

如您所见,这非常简单。创建一个用户列表,强制到一个数组,启动一个 watch ,遍历列表并调用一个方法,停止 watch 。重复。通过返回第一次运行和第二次运行的差异来完成。

现在我用这些打电话:

differenceList = Enumerable
                 .Range(0, 50)
                 .Select(currentItem => ReturnDifferenceA()).ToList();
average = differenceList.Average();

differenceListA = Enumerable
                  .Range(0, 50)
                  .Select(currentItem => ReturnDifferenceA()).ToList();
averageA = differenceListA.Average();

differenceListB = Enumerable
                  .Range(0, 50)
                  .Select(currentItem => ReturnDifferenceA()).ToList();
averageB = differenceListB.Average();

现在有趣的是,所有平均值都相对较大地为正,范围从 150k 到 300k ticks。

我不明白的是,我正在以相同的方式、相同的方法浏览相同的列表,但是却存在如此大的差异。是否正在进行某种缓存?

另一个有趣的事情是,如果我在第一个秒表部分之前遍历列表,平均值约为 5k 左右。

最佳答案

您正在使用高级语言运行,其运行时环境会进行大量缓存和性能优化,这很常见。有时它被称为预热虚拟机,或预热服务器(当它是生产应用程序时)。

如果要重复执行某项操作,那么您会经常注意到第一次测量的运行时间较长,而其余时间应该趋于平稳。

我在 MATLAB 代码中执行此操作,发现我第一次运行基准测试循环需要五秒钟,随后的时间需要五分之一秒。这是一个巨大的差异,因为它是一种需要某种形式的编译的解释型语言,但实际上,它不会影响您的性能,因为绝大多数在任何生产应用程序中都是“第二次”。

关于C#、For 循环和速度测试……完全相同的循环第二次更快?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/303343/

相关文章:

c# - 在 C# 项目中引用 exe 文件是一种不好的做法吗

c# - 三元运算符和协变强制

arrays - 在 Swift 中将索引数组转换为字典

arrays - 使用 Parse 查询填充数组 (Swift)

c# - 通过 parent child 的多个 Foreach 循环

c# - 关于 session 的教学?

c - 函数中调用的函数 C 中使用的二维动态数组参数不起作用

javascript - 鉴于 for...in 结构,库提供的函数(如 jQuery.map() 或 _.each())有什么用?

asp.net - 如果每个循环的 ASP.NET MVC 为空,则显示自定义文本

c# - .NET Core 2 中的 ReadAsMultipartAsync 等价物