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;
}

正如你所看到的,这是非常简单的。创建用户的列表,强制到一个数组,启动手表,遍历列表并调用一个方法,秒表。重复。通过返回来自第一运行和第二差完成。。

现在我使用这些调用:

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的蜱。

我不明白的是,我要通过相同的列表,以同样的方式,用同样的方法,但存在这样的差异。是否有某种类型的缓存怎么回事?

另一个有趣的事情是,如果我遍历列表前的第一站表款,平均值大约5K左右。

有帮助吗?

解决方案

顺便说一下,在一个阵列使用IEnumerable.Count()比Array.Length慢数百倍。虽然这并不回答这个问题在所有的

其他提示

您在使用的运行时环境做了很多的缓存和性能优化高级语言运行时,这是常见的。有时它被称为预热的虚拟机,或者预热服务器(当它是一个生产应用程序)。

如果事情将要反复做,那么你会经常在第一时间通知具有较大的测量运行,其余应平整,以较小的量。

我为此在MATLAB代码,并看到第一次运行的基准循环时,会五秒钟,随后的时间进行第二次的五分之一。这是一个巨大的差异,因为它是需要某种形式编制的解释语言,但在现实中,它不会影响你的表现,因为绝大多数将是“第二次在任何生产中的应用。

它很可能是DoThings()不是JIT编译为本机代码在第一次被调用,直到

由于.NET,像Java平台,是一个JIT环境。所有高级.NET代码被编译成微软的中间语言的字节码。

要运行程序,此字节码需要编译/翻译成机器码。然而,编译.NET编程文件不存储在本机机器代码,但在中间的虚拟机的字节码。

在第一次运行时编译JIT,所以花了更多的时间。 在随后的运行中不再需要被JIT编译,但是本机代码从JIT缓存绘制的,所以它应该是更快的。

你保持你的应用而不终止的后续运行?然后,第二个原因也是由于VM。 (VM:1 =虚拟机; VM:2 =虚拟存储器)。所有现代通用操作系统上运行的虚拟内存,这是地图上真正的记忆过程,允许操作系统来管理和优化使用系统资源的能力。较少使用过程经常扫关闭成磁盘高速缓存,以让其它进程有资源的最佳使用。

您过程是不是在虚拟存储器中的第一时间,所以它具有遭受被扫进存储器的开销。因为随后,你的过程是最近使用的顶级列表(又名在最近最少使用列表的底部)中,它没有灭扫到磁盘缓存呢。

此外,资源由OS根据需要少量地分给你的过程。所以对于第一轮,你的进程不得不通过推信封争与OS扩大其资源界限的痛苦。

一个虚拟机允许.NET和Java抽象最编程特性成与机器无关的层,分离并因此离开所述机器依赖软件工程师来处理较小的混乱。尽管微软的Windows上运行,而统一的x86硬件后裔,有不同的操作系统版本和CPU型号足够差异,为了给.NET程序员和用户的一致视图保证抽象的虚拟机。

你说你没有得到做3次,第2次和第3次是比较接近的。在我看来,这只是第一次直通循环,事情是缓慢的。

我怀疑你调用的函数是不是刚刚在计时,直到第一次运行。你可以尝试一次运行它,然后停止并重新运行。没有代码的变化,刚刚在时间从以前的运行编译应该还是OK的,你看不到任何剩余的优化是的实际的工作缓存影响。

我们暂且升温缓存的VM或机器,JIT优化,一会儿的事:还有什么是你的电脑做什么?是否有任何的3e42系统服务和任务栏一样的东西抓住一些CPU?也许你的Steam客户端决定检查更新,或IE需要做一些可怕重要的,否则你的防病毒程序的方式?

您测试仅作,你可以从所有在你的机器上运行的其他软件隔离开度有用。的软件,你可能可以每位关闭尝试测量运行前。

但后来我知道什么? - 也许你的测量方法由.NET(或其他)管理的运行时也和只占运行时“虚拟周期”

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top