如何从C#中的QueryPerformancecount

问题描述 投票:0回答:5
我需要替换秒表以避免使用getters的属性。我将使用QueryPerformanceCounter实施它。

我只需要tick别无其他。

任何人都可以提供代码狙击手,以获取正确的刻度(MS的1/10000)或任何其他小但稳定的价值。 请注意,请注意我的服务器将时钟粒度设置为

0.5ms

(不确定它是否会影响QueryPerformanceCounter),而只是让您知道。

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

为了避免混乱,我真的想知道QueryPerformanceCounter中的

lpperformanceCount

(Out long lpperformancecount);

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

c# .net-4.0
5个回答
13
投票

Stopwatch.GetTimestamp

您不必实例化

Stopwatch

对象,
GetTimestamp

无论其上下文如何,都应返回tick的数量。

[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

6
投票
老了,但它仍然应该有效

eDIT:StopWatch的内部实际使用

QueryPerformanceCounter

,因此使用托管代码应提供相同的结果,并具有更好的兼容性。

不要在不进行测试的情况下使用秒表来进行高分辨率计时。自从我测试它已经有几年了,但是当时它给出了默认的Windows时间分辨率。您可以说出,因为如果使用默认的Windows分辨率,则实际上非常快,需要0时间或10-15毫秒(默认的分辨率实际上是线程上下文开关的分辨率,大概是在每个上下文开关上更新默认的Windows时钟,这是每一个上下文开关,大约是每10-15毫秒毫秒)。
    
我使用以下类,使我的系统上的时间准确至100N。

public class MStopwatch : Stopwatch { private double _frequencyScaler; public MStopwatch() { _frequencyScaler = 1.0 / Stopwatch.Frequency; } public double ElapsedSeconds { get { return ElapsedTicks * _frequencyScaler; } } }

3
投票

没有直接答案(但潜在的必要支持信息如下):

2
投票
提供的答案中的某些可以直接回答您的问题。 但是,为了完成您要做的事情,我想添加几个笔记。 首先,考虑到在运行时发生的即时(JIT)编译器的时间开销。 您抓取初始时间戳的任何代码,然后进行

Stuff

,然后抓取最终时间戳以减去三角洲的T2-T1,对于
Stuff
内部的任何功能,如果您在当前过程中包含任何尚未打电话的功能,则首次调用它,您将付费,以将其付费,以将Bytecode付费到本机代码中。 在这种情况下,成本并不代表绩效关键代码的实际运行时成本,该代码可能是经常称为的代码,而其JIT成本仅支付一次(在此过程中首次调用)。 因此,多次调用定时代码,丢弃第一个计时,然后平均进行。

0
投票
stuff

包括分配新物体的代码,那么它可能会启动垃圾收集器,这将很昂贵,因此为您可能想扔掉的一些潜在异常值做好准备。

第二,好的答案提供了代码来声明外部功能以从系统DLL呼叫,这很棒。 在一般情况下,正确使这些签名正确,有时可能是一种滋扰,因此我想为此提及一个很好的资源:pinvoke.net。 搜索QueryPerformanceCounter为我提供了签名,使我脱离了已经给出的答案,这是您想要进行的任何系统调用的绝佳资源。


http://pinvoke.net/search.aspx?search = queryPerformanceCounter&namespace = [all]

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

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.