【问题标题】:Python 2.x - QueryPerformanceCounter() on WindowsPython 2.x - Windows 上的 QueryPerformanceCounter()
【发布时间】:2016-11-22 12:20:16
【问题描述】:

我想用 Python 编写我自己的时钟对象。我希望它非常非常准确。我在 Windows 上读到了,我可以使用 QueryPerformanceCounter()。但是怎么做?我不知道任何C;只有 Python 2.x。

谁能给我一个提示,告诉我如何在 Python 中使用它来在 Win 上制作准确的时钟?

【问题讨论】:

  • QueryPerformanceCounter() 在哪里? Windows API?
  • 谢谢。我现在正在做一些测试,我确信我有一个解决方案。继续看:)
  • 那太好了,谢谢!
  • 好的,我现在想通了。我不完全理解的是该函数的用法,它在失败时返回(在文档中编写)仅返回零,成功时返回非零。你知道吗?

标签: python windows time clock performancecounter


【解决方案1】:

我已使用 ctypes 模块将您提供的 C++ example 移植到 Python:

C++

LARGE_INTEGER StartingTime, EndingTime, ElapsedMicroseconds;
LARGE_INTEGER Frequency;

QueryPerformanceFrequency(&Frequency); 
QueryPerformanceCounter(&StartingTime);

// Activity to be timed

QueryPerformanceCounter(&EndingTime);
ElapsedMicroseconds.QuadPart = EndingTime.QuadPart - StartingTime.QuadPart;

ElapsedMicroseconds.QuadPart *= 1000000;
ElapsedMicroseconds.QuadPart /= Frequency.QuadPart;

Python

import ctypes
import ctypes.wintypes
import time

kernel32             = ctypes.WinDLL('kernel32', use_last_error=True)

starting_time        = ctypes.wintypes.LARGE_INTEGER()
ending_time          = ctypes.wintypes.LARGE_INTEGER()
elapsed_microseconds = ctypes.wintypes.LARGE_INTEGER()
frequency            = ctypes.wintypes.LARGE_INTEGER()

kernel32.QueryPerformanceFrequency(ctypes.byref(frequency)) 
kernel32.QueryPerformanceCounter(ctypes.byref(starting_time))

# Activity to be timed, e.g.
time.sleep(2)

kernel32.QueryPerformanceCounter(ctypes.byref(ending_time))

elapsed_microseconds = ending_time.value - starting_time.value
elapsed_microseconds *= 1000000
elapsed_microseconds /= frequency.value

print(elapsed_microseconds)

我非常感谢 @eryksun 的有用提示!

上面的代码应该打印出接近2000000 的内容(例如2000248.7442040185,该值可能会不时不同)。您也可以使用round()int() 函数来去除小数。

正如@eryksun 所说,您也可以使用time.clock(),它是用C 实现的,也使用QueryPerformanceCounter()

示例与使用 ctypes 的示例完全相同:

import time
starting_time = time.clock()

# Activity to be timed, e.g.
time.sleep(2)

ending_time = time.clock()

elapsed_microseconds = ending_time - starting_time
elapsed_microseconds *= 1000000

print(elapsed_microseconds)

希望这会有所帮助!

【讨论】:

  • 非常感谢您的努力,但我想如果不学习 C 语言,我就无法让它工作。我不了解 C 类型,因此无法修复您提供的解决方法
  • 嗯好的。如果您有时在 SO 上,如果我有更多想法,我可以给您评论。
  • 我刚刚发现这些 c_longlong_Array_1 对象是可迭代的,而 obj[0] 是我认为的时间值: Try "ElapsedMicroseconds = EndingTime[0] - StartingTime[0]"
  • 避免windll。其他一些基于 ctypes 的库可能会在同一个脚本中使用,但使用 restypeargtypeserrcheck 的定义会破坏您的代码。而是使用kernel32 = ctypes.WinDLL('kernel32', use_last_error=True)。在支持 Windows last 错误值的函数上设置errcheck 属性(请参阅文档),您可以通过ctypes.get_last_error() 安全地获取该值,并通过ctypes.WinError(code) 获取异常。对 Windows 数据类型使用 ctypes.wintypes,例如 st = wintypes.LARGE_INTEGER(); kernel32.QueryPerformanceCounter(ctypes.byref(st))
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多