在.NET以毫秒为单位测量code速度 [英] Measure code speed in .net in milliseconds

查看:103
本文介绍了在.NET以毫秒为单位测量code速度的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想获得最大计数我必须执行一个循环为它拍摄X毫秒才能完成。

有关,例如。

  INT GetIterationsForExecutionTime(INT MS)
{
    诠释计数= 0;
    / *伪code
    做
        一些code在这里
        算上++;
    直到executionTime>女士
    * /

    返回计数;
}
 

我如何做到这样的事?

解决方案
  

我想获得最大计数我必须执行一个循环为它拍摄X毫秒才能完成。

首先,根本就没有做到这一点。如果你需要等待一定的毫秒数不要忙等在循环。相反,启动一个定时器的并返回。当计时器滴答,有它调用恢复您离开的地方的方法。该 Task.Delay 方法可能是一个很好的使用;它需要照顾的定时为您详细介绍。

如果你的问题其实是如何的时间时,一些code需要,那么你需要比只是一个很好的计时器更量。有很多的艺术和科学,以获得准确的计时。

首先,你应该始终使用秒表,从不使用 DateTime.Now 这些时序。秒表被设计为一个高precision计时器告诉你的多少时间过去了的。 DateTime.Now 是一个低precision计时器告诉你的如果是时间看医生是谁尚未的。你不会使用挂钟时间奥林匹克竞赛;你会使用最高precision秒表,你可以把你的手。因此,使用为您提供了一个。

其次,你需要记住的 C#code编译准时的。因此,第一次通过循环可以有几百或几千倍比以后每一次更加昂贵,由于抖动分析code环路通话费用。如果您打算在测量循环的温暖的成本,那么你需要在的你开始计时它运行循环一次的。如果您打算在测量的平均值的成本的包括JIT时间的,那么你需要决定多少次拼成试验的合理数量,使平均正常工作了

第三,你需要的请确保你不穿任何铅块当您运行的。永远不要让性能测量的在调试的。令人惊奇的是谁的人做到这一点的数量。如果你是在调试器则运行时可能的谈来回调试器的,以确保你得到你想要的调试经验,并且喋喋不休需要时间。抖动产生的糟糕code 的比通常那样,让你的调试体验更加一致。垃圾收集器的少收些积极的。等等。始终运行性能测试调试器之外,并与优化开机。

第四,记住的虚拟内存系统对类似的紧张不安。的成本。如果您已经在运行的管理程序,或者最近运行的一个,那么在CLR的,你需要的页面可能热 - 已经在RAM中 - 他们是快速。如果不是,则该网页可以是冷,在磁盘上,并且需要页故障在,这可以极大地改变定时。

五,记住的的抖动可以让你不要指望的优化。如果您尝试时间:

  //让我们的时间除!
的for(int i = 0; I< 1000000; ++ I){诠释J = I + 1; }
 

抖动的完全有权利删除整个环的。它可以实现循环计算不用于其他任何地方的程序,并完全删除它的价值,给它的的时间。是否如此?有可能。也许不会。这是到的抖动。你应该测量的现实code 的,这里计算的值,实际使用某种方式表现;那么抖动就会知道,它不能优化他们离开。

六,其中创建大量垃圾的试验定时可以被垃圾收集器揭去。假设你有两个测试,一个使大量的垃圾和一个使一点点。由第一测试所产生的垃圾的收集的成本可以被充电,以运行第二个测试,如果靠运气第一测试设法不集合上运行,但第二测试触发一个所需的时间。如果你的测试产生大量的垃圾再考虑(1)是我的测试现实的开始呢?它没有任何意义,做一个不切实际的方案的性能测试,因为你不能很好地推论到你真正的程序将如何表现。 (2)我应该是垃圾收集的成本充电所产生垃圾的考验吗?如果是这样,那么请确保您的测试完成的时间之前强制全额征收。

第七,您正在运行你的code在多线程,多处理器环境中,线程可以随意切换,并在该线程量子(时间操作系统会给另一个线程,直到你可能会得到一个机会的金额再次运行)为约16毫秒。 16毫秒左右的 50000000处理器周期的。未来与亚毫秒的操作准确的计时可如果线程切换中,你正试图测量数百万处理器周期中的一个发生了相当的难度。考虑到这一点。

I want to get the maximum count I have to execute a loop for it to take x milliseconds to finish.

For eg.

int GetIterationsForExecutionTime(int ms)
{
    int count = 0;
    /* pseudocode 
    do
        some code here
        count++;
    until executionTime > ms
    */

    return count;
}

How do I accomplish something like this?

解决方案

I want to get the maximum count I have to execute a loop for it to take x milliseconds to finish.

First off, simply do not do that. If you need to wait a certain number of milliseconds do not busy-wait in a loop. Rather, start a timer and return. When the timer ticks, have it call a method that resumes where you left off. The Task.Delay method might be a good one to use; it takes care of the timer details for you.

If your question is actually about how to time the amount of time that some code takes then you need much more than simply a good timer. There is a lot of art and science to getting accurate timings.

First you should always use Stopwatch and never use DateTime.Now for these timings. Stopwatch is designed to be a high-precision timer for telling you how much time elapsed. DateTime.Now is a low-precision timer for telling you if it is time to watch Doctor Who yet. You wouldn't use a wall clock to time an Olympic race; you'd use the highest precision stopwatch you could get your hands on. So use the one provided for you.

Second, you need to remember that C# code is compiled Just In Time. The first time you go through a loop can therefore be hundreds or thousands of times more expensive than every subsequent time due to the cost of the jitter analyzing the code that the loop calls. If you are intending on measuring the "warm" cost of a loop then you need to run the loop once before you start timing it. If you are intending on measuring the average cost including the jit time then you need to decide how many times makes up a reasonable number of trials, so that the average works out correctly.

Third, you need to make sure that you are not wearing any lead weights when you are running. Never make performance measurements while debugging. It is astonishing the number of people who do this. If you are in the debugger then the runtime may be talking back and forth with the debugger to make sure that you are getting the debugging experience you want, and that chatter takes time. The jitter is generating worse code than it normally would, so that your debugging experience is more consistent. The garbage collector is collecting less aggressively. And so on. Always run your performance measurements outside the debugger, and with optimizations turned on.

Fourth, remember that virtual memory systems impose costs similar to those of jitters. If you are already running a managed program, or have recently run one, then the pages of the CLR that you need are likely "hot" -- already in RAM -- where they are fast. If not, then the pages might be cold, on disk, and need to be page faulted in. That can change timings enormously.

Fifth, remember that the jitter can make optimizations that you do not expect. If you try to time:

// Let's time addition!
for (int i = 0; i < 1000000; ++i) { int j = i + 1; }

the jitter is entirely within its rights to remove the entire loop. It can realize that the loop computes no value that is used anywhere else in the program and remove it entirely, giving it a time of zero. Does it do so? Maybe. Maybe not. That's up to the jitter. You should measure the performance of realistic code, where the values computed are actually used somehow; the jitter will then know that it cannot optimize them away.

Sixth, timings of tests which create lots of garbage can be thrown off by the garbage collector. Suppose you have two tests, one that makes a lot of garbage and one that makes a little bit. The cost of the collection of the garbage produced by the first test can be "charged" to the time taken to run the second test if by luck the first test manages to run without a collection but the second test triggers one. If your tests produce a lot of garbage then consider (1) is my test realistic to begin with? It doesn't make any sense to do a performance measurement of an unrealistic program because you cannot make good inferences to how your real program will behave. And (2) should I be charging the cost of garbage collection to the test that produced the garbage? If so, then make sure that you force a full collection before the timing of the test is done.

Seventh, you are running your code in a multithreaded, multiprocessor environment where threads can be switched at will, and where the thread quantum (the amount of time the operating system will give another thread until yours might get a chance to run again) is about 16 milliseconds. 16 milliseconds is about fifty million processor cycles. Coming up with accurate timings of sub-millisecond operations can be quite difficult if the thread switch happens within one of the several million processor cycles that you are trying to measure. Take that into consideration.

这篇关于在.NET以毫秒为单位测量code速度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆