如何从C#中的QueryPerformanceCounter获取刻度?

我需要替换秒表以避免使用getter作为其属性。 我将使用QueryPerformanceCounter实现它。 我只需要其他任何东西。

任何人都可以提供代码snipet,以获得正确的滴答(1/10000毫秒)或任何其他小而稳定的值。

请注意我的服务器将时钟粒度设置为0.5毫秒 (不确定它是否会影响QueryPerformanceCounter),但只是让你知道。

请注意 – 我不需要计时器。 我只需要测量代码部分之间的时间间隔。

编辑:为了避免混淆我真的想知道QueryPerformanceCounter中的lpPerformanceCount是什么(超长lpPerformanceCount);

 [DllImport("Kernel32.dll")] private static extern bool QueryPerformanceCounter(out long lpPerformanceCount); [DllImport("Kernel32.dll")] private static extern bool QueryPerformanceFrequency(out long lpFrequency); 

取自http://www.codeproject.com/Articles/2635/High-Performance-Timer-in-C

旧但它应该仍然有效

编辑: StopWatch的内部实际上使用QueryPerformanceCounter ,因此使用托管代码应该提供相同的结果,具有更好的兼容性。

http://msdn.microsoft.com/en-us/library/system.diagnostics.stopwatch.gettimestamp.aspx

Stopwatch.GetTimestamp

您不必实例化Stopwatch对象, GetTimestamp应返回刻度数,而不管其上下文如何。

不测试时,请勿使用StopWatch进行高分辨率计时。 我测试它已经有几年了,但那时它给出了默认的窗口时间分辨率。 你可以说,因为如果它使用默认的窗口分辨率(默认分辨率实际上是线程上下文切换的分辨率,实际上默认的窗口时钟在每个上下文中更新),真的,非常快的事情将花费0或10-15毫秒开关,大约每10-15毫秒)。

不是直接的答案(但可能需要支持信息如下):

一些提供的答案非常适合直接回答您的问题。 但是,为了完成你想要做的事情,我想补充几个笔记。

首先,考虑在运行时发生的实时(jit)编译器的时序开销。 获取初始时间戳然后执行操作的任何代码,然后获取最终时间戳以减去delta的t2-t1,对于内容中的任何function,如果包含在当前进程中尚未调用的任何函数则第一次调用它时,您将支付jit开销以将字节码编译为本机代码。 在这种情况下,成本并不代表性能关键代码的实际运行时成本,这可能是频繁调用的代码,但其jit成本仅支付一次(在此过程中首次调用它)。 因此,多次调用定时代码,抛出第一个时间,然后取平均值。

此外,请注意垃圾收集器的运行时成本。 如果您只是在玩游戏,那么对可以严格避免分配新对象的代码进行基准测试可能是有趣的。 但有时这并不容易,特别是当您调用其实现无法更改的函数时。 此外,我必须告诉你,生产代码的实际性能开销无法避免垃圾收集开销,因此获得一个真实的数字应该包括这个开销。 也就是说,如果你的东西包含分配新对象的代码,那么它可能会启动垃圾收集器,这将是昂贵的,所以准备好你可能想要抛弃的一些潜在的exception值。

其次,好的答案提供了代码来声明从系统dll调用的外部函数,这很好。 在一般情况下使这些签名正确可能会令人讨厌,所以我想提一个很好的资源:pinvoke.net。 搜索QueryPerformanceCounter给了我一些签名,这些签名让我对已经给出的答案进行了剪切和粘贴,它是您想要进行的任何系统调用的绝佳资源。

http://pinvoke.net/search.aspx?search=QueryPerformanceCounter&namespace=%5BAll%5D

 I don't remember from where I copied it, but this code works well for me: public class QueryPerfCounter { [DllImport("KERNEL32")] private static extern bool QueryPerformanceCounter(out long lpPerformanceCount); [DllImport("Kernel32.dll")] private static extern bool QueryPerformanceFrequency(out long lpFrequency); private long start; private long stop; private long frequency; double multiplier = 1.0e6; // usecs / sec public QueryPerfCounter() { if (QueryPerformanceFrequency(out frequency) == false) { // Frequency not supported throw new Win32Exception(); } } public void Start() { QueryPerformanceCounter(out start); } public void Stop() { QueryPerformanceCounter(out stop); } public double Duration(int iterations) { return ((((stop - start) * multiplier) / frequency) / iterations); } }