运行托管应用程序第二次表现出了比第一次

问题描述:

我有一个基准测试应用程序来测试我写了一些API的性能不同的表现。在这个基准测试应用程序中,我基本上使用QueryPerformanceCounter,并通过在调用API之后和之前将QPC值的差异除以频率来获得时间。但是基准测试结果似乎有所不同如果我从不同的驱动器运行应用程序(在同一套Dll上运行相同的可执行文件)。另外,在特定的驱动器上,第一次运行应用程序,关闭应用程序并重新运行它会产生不同的基准测试结果。谁能解释这种行为?我在这里错过了什么吗?运行托管应用程序第二次表现出了比第一次

一些更多有用信息:

的行为是这样的:运行该应用程序,关闭它,并重新运行它,在基准测试结果看来,以提高对第二次运行和以后保持不变。这种行为在从C驱动器运行的情况下更为突出。 我还想提一下,我的基准测试应用程序可以选择重新运行/重新测试特定的API,而无需关闭应用程序。我确实知道存在着点击事件,但我不明白的是,在第一次运行应用程序时,如果您多次重新运行API而未关闭应用程序,则在运行几次后性能会稳定下来,然后关闭并重新运行同样的考验,表现似乎有所改善。

此外,如何做到从不同的驱动器上运行,当你考虑性能的变化?

[信息更新]

我做了一个NGEN现在不同的运行从同一位置消失之间的性能差异。即如果我打开基准测试应用程序,运行一次,关闭它并从同一位置重新运行它,它会显示相同的值。

但现在我已经遇到的另一个问题。当我从D驱动器启动应用程序并运行它几次(在基准编程的同一次启动中几次API迭代),然后从第三次迭代开始,所有API的性能似乎下降了大约20% 。然后,如果关闭并重新启动应用程序并运行它,对于前2次迭代,它会给出正确的值(与从C获得的值相同),然后性能再次下降。从C驱动器运行时看不到此行为。从C盘开始,无论你运行多少次运行,它都是非常一致的。

我使用大双阵列来测试我的API的性能。我担心GC会在测试之间进行,所以我在每次测试之前和之后明确地呼叫GC.Collect()& GC.WaitForPendingFinalizers()。所以我不认为它与GC有任何关系。

我试着使用AQ时间知道什么从3日开始迭代发生,但有趣的是,当我运行与AQ时间剖析它的应用程序,性能不倒的。

如不提出任何有趣的IO活动的性能计数器。

感谢 NIRANJAN

+0

科里对一个可能的问题做出了正确的回答。但是,如果您可以详细说明结果,则会有所帮助。例如,如果第二轮是WORSE,那么这是一个不同的故事。 :) – BobbyShaftoe 2009-01-23 06:14:11

+0

道歉以前不描述。行为如下: 运行应用程序,关闭它并重新运行一次,基准测试结果在第二次运行中似乎有所改善,此后保持不变。这种行为在从C驱动器运行的情况下更为突出。 – 2009-01-23 08:31:59

我觉得这里有效果的组合:

首先,每次运行相同的功能测试工具中多次,使用相同的数据,将有可能提高,因为:

  • JIT编译优化将是(由科里福伊为mentioned already)运行最频繁的提高性能的代码
  • 程序代码会在磁盘缓存(如mentioned already由Crashwork)
  • 一些程序代码将在CPU缓存如果它足够小,执行频率足够高

如果数据不同的测试工具中的功能,每次运行,这可以解释为什么关闭和运行测试工具再次改进了结果:数据现在将位于磁盘缓存中,这不是第一次。

最后,是的,即使两个“驱动”是同一个物理磁盘上,他们将有不同的表现:可以读取数据从盘片比内外部更快。如果它们是不同的物理磁盘,那么性能差异似乎很可能。另外,一个磁盘可能比另一个磁盘碎片更多,导致更长的查找时间和更慢的数据传输速率。

是。它被称为Just-In-Time compiling。基本上,您的应用程序部署为MSIL(Microsoft中间语言),并且在第一次运行时它会转换为本机代码。

你总是可以运行NGEN(见上面的文章),或在你的性能测试脚本一个温暖期在那里通过实际情景基准业绩之前运行了好几次。

运行的应用程序带来了从硬盘驱动器到操作系统的磁盘缓存(在RAM)的可执行文件和其他文件。如果之后很快再次运行,这些文件中的很多文件可能仍处于缓存中。 RAM比磁盘快得多。

当然还有一盘可能比另一个更快。

此外,其他因素可能开始发挥作用。机器上的文件系统缓存,最近使用的数据的缓冲等

最佳运行几个测试(或几百!)和整个组平均出来的,除非你是专门测量冷启动时间。