我的静态方法似乎在重复使用方面的性能更快.为什么?它会被缓存吗?



我创建了代码,以查看我的静态压缩方法执行的速度,我注意到第一个执行需要8,500,000纳秒纳秒,第二个纳秒大约是一半,然后在此之后的所有操作都执行。0纳秒。为什么?

private void CheckPerformance()
{
    while (KeepRunning)
    {
        //generates a complex random 500 character string
        string text = GenerateString(500, 4);

        DateTime beginTime = DateTime.Now;
        byte[] bytes = Compress(text); // < - timing this
        long elapsedTicks = DateTime.Now.Ticks - beginTime.Ticks;
        Console.WriteLine("   {0:N0} nanoseconds", elapsedTicks * 100);
        //sleep for 5 seconds
        Thread.Sleep(5000);
    }
}
public static byte[] Compress(string text)
{
    using (MemoryStream output = new MemoryStream())
    {
        using (DeflateStream ds = new DeflateStream(output, CompressionMode.Compress))
        {
            using (StreamWriter writer = new StreamWriter(ds, Encoding.UTF8))
            {
                writer.Write(text);
            }
        }
        return output.ToArray();
    }
}

DateTime.Now每秒获得大约10次更新,但不要引用我(可能取决于硬件和软件设置)。它也很慢,因为它需要弄清楚该系统在哪个时区。UtcNow速度更快,但仍会被缓存一些。因此,它可以在后续呼叫上使用缓存版本。

使用StopWatch代替更准确的测量。StopWatch通过使用硬件使用高精度。您可以使用Stopwatch.IsHighResolution检查。

using System.Diagnostics;
Stopwatch sw = new Stopwatch();
sw.Start();
// code to benchmark 
sw.Stop();

让我们看看您是否获得相同的指标。

编辑

确实需要编译您的方法,但差异不能是由于jit汇编而引起的,因为它只会是jit汇编的一次(并非总是总是,但在您的情况下它将是一次),然后再利用。因此,只有第一个呼叫应花费更长的时间,并且随后的呼叫应相同。要丢弃此假设,只需在基准测试阶段之外调用Compress,就可以编译JIT。然后基准测试,现在不会发生JIT汇编,DateTime仍然会给您随机结果。

注意:JIT编译器不一定总是将整个方法汇编为机器代码,而仅当执行通过代码时。因此,如果您有if语句,则可能不会汇编块,直到执行通过块。但是您的没有语句,所以这就是为什么它将被汇编一次。

此外,我们不能自信地说,这是由于jit汇编而引起的,因为可能会嵌入Compress方法,但是在您的情况下,它很可能没有列入,因为您很可能会进行调试器,因此,JIT优化将会优化,因此被禁用。

尝试此代码,您会注意到它为经过的时间提供随机结果,即使执行相同的代码:

for (int i = 0; i < 1000; i++)
{
    DateTime beginTime = DateTime.UtcNow;
    var sw = Stopwatch.StartNew();
    while (sw.ElapsedTicks < 100)
    {
        Console.WriteLine("*");
    }
    long elapsedTicks = DateTime.UtcNow.Ticks - beginTime.Ticks;
    Console.WriteLine("   {0:N0} nanoseconds", elapsedTicks * 100);
}

在我的系统上,如果我将此行更改为 sw.ElapsedTicks < 2050,则总有持续报告的非零的差异。这意味着在DateTime.Now获得新值而不是使用缓存的值时。

总而言之,我不购买JIT汇编是您注意到的内容的解释。

第一次击打时,它会被打在一起。所以这需要时间。不知道为什么第二次和第三次有所不同。

相关内容

  • 没有找到相关文章

最新更新