0

在 FreeBSD 上测试 Python 的 time.clock() 函数时,我注意到它总是返回相同的值,大约为 0.156

time.time() 函数可以正常工作,但我需要一个分辨率稍高的东西。

有没有人绑定它的 C 函数,是否有替代的高分辨率计时器?

我没有进行分析,所以 TimeIt 模块在这里并不合适。

4

4 回答 4

3

Python 的 time.clock 调用 C 函数 clock(3) -man clock应该确认它应该在 BSD 上工作,所以我不知道为什么它不适合你。也许您可以尝试通过ctypes直接从系统 C 库调用时钟函数来解决 Python 端口中的这个明显错误(如果您将库称为 .so/.dynlib/.dll 或调用任何动态共享库自由BSD)?

顺便说一句,time.time 应该是非常高分辨率的,因为它在内部调用 gettimeofday (好吧,无论如何,在正确构建的 Python 中) - 你在系统上观察到什么分辨率?

编辑:这是wat.c一个特定于 BSD 的扩展(仅在我的 Mac 上测试过——抱歉,我手头没有其他 BSD 风格)来解决这个明显的 FreeBSD 端口问题:

#include "Python.h"
#include <sys/time.h>

static PyObject *
wat_time(PyObject *self, PyObject *args)
{
    struct timeval t;
    if (gettimeofday(&t, (struct timezone *)NULL) == 0) {
        double result = (double)t.tv_sec + t.tv_usec*0.000001;
        return PyFloat_FromDouble(result);
    }
    return PyErr_SetFromErrno(PyExc_OSError);
}

static PyMethodDef wat_methods[] = {
      {"time",      wat_time,       METH_VARARGS,
       PyDoc_STR("time() -> microseconds since epoch")},
      {NULL,        NULL}       /* sentinel */
};

PyDoc_STRVAR(wat_module_doc,
"Workaround for time.time issues on FreeBsd.");

PyMODINIT_FUNC
initwat(void)
{
    Py_InitModule3("wat", wat_methods, wat_module_doc);
}

这是setup.py放在同一目录中的:

from distutils.core import setup, Extension

setup (name = "wat",
       version = "0.1",
       maintainer = "Alex Martelli",
       maintainer_email = "aleaxit@gmail.com",
       url = "http://www.aleax.it/wat.zip",
       description = "WorkAround for Time in FreeBSD",
       ext_modules = [Extension('wat', sources=['wat.c'])],
)

URL 是正确的,因此您也可以在此处压缩这两个文件。

要构建和安装此扩展,python setup.py install(如果您有权在 Python 安装中写入)或python setup.py build_ext -i在放置源代码的目录中写入 wat.so(然后手动将其移动到您喜欢的任何位置,但首先试一试,例如python -c'import wat; print repr(wat.time())'在您构建它的同一目录中)。

请让我知道它在 FreeBSD(或任何其他带有gettimeofday!- 的 Unix 风格)上是如何工作的——如果 C 编译器抱怨gettimeofday,你可能在一个不想看到它的第二个参数的系统上,试试没有它!- )。

于 2009-07-10T15:11:20.250 回答
1

time.clock()返回 UNIX 系统上的 CPU 时间,以及自 Windows 上程序启动以来的挂钟时间。在我看来,这是一个非常不幸的不对称。

您可以在此处time.time()的 Python 源代码中找到 的定义(链接到 Google 代码搜索)。它似乎使用了可用的最高分辨率计时器,根据快速谷歌搜索,它也在 FreeBSD 上,并且应该在微秒精度级别。gettimeofday()

但是,如果您真的需要更高的精度,您可以考虑编写自己的 C 模块以获得真正的高分辨率计时(可能只返回当前的微秒计数!)。Pyrex使 Python 扩展编写变得非常轻松,而SWIG是另一个常见的选择。(虽然真的,如果你想把你的计时器精确度减少多少微秒,只需自己编写一个纯 C Python 扩展。)Ctypes 也是一种选择,但可能相当慢。

祝你好运!

于 2009-07-10T15:11:54.180 回答
1

time.clock() 返回处理器时间。也就是说,当前进程在处理器上使用了多少时间。因此,如果您有一个名为“clock.py”的 Python 脚本,那么import time;print time.clock()每次运行它时它确实会打印完全相同的内容,因为每次都会启动一个新进程。

这是一个 python 控制台日志,可能会向您解释:

>>> import time
>>> time.clock()
0.11
>>> time.clock()
0.11
>>> time.clock()
0.11
>>> for x in xrange(100000000): pass
... 
>>> time.clock()
7.7800000000000002
>>> time.clock()
7.7800000000000002
>>> time.clock()
7.7800000000000002

我希望这可以澄清事情。

于 2009-07-10T15:37:25.383 回答
0

time.clock() 被实现为返回一个双精度值

 ((double)clock()) / CLOCKS_PER_SEC

为什么你认为 time.time() 的分辨率不好?它使用gettimeofday,它反过来读取具有非常好的分辨率的硬件时钟。

于 2009-07-10T15:12:58.717 回答