FreeBSD 上的 Python 时钟函数

发布于 2024-07-26 20:41:03 字数 194 浏览 5 评论 0原文

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

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

有人知道它所绑定的 C 函数吗?是否有替代的高分辨率计时器?

我不是在进行分析,因此 TimeIt 模块在这里并不合适。

While testing Pythons time.clock() function on FreeBSD I've noticed it always returns the same value, around 0.156

The time.time() function works properly but I need a something with a slightly higher resolution.

Does anyone the C function it's bound to and if there is an alternative high resolution timer?

I'm not profiling so the TimeIt module is not really appropriate here.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

暖伴 2024-08-02 20:41:03

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

顺便说一句,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 = "[email protected]",
       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 在您放置源代码的目录(然后手动将其移动到您喜欢的任何位置,但首先尝试一下,例如使用 python -c'import wat; print repr(wat.time())' 在您构建它的同一目录中)。

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

Python's time.clock calls C function clock(3) -- man clock should confirm that it's supposed to work on BSD, so I don't know why it's not working for you. Maybe you can try working around this apparent bug in your Python port by using ctypes to call the clock function from the system C library directly (if you have said library as a .so/.dynlib/.dll or whatever dynamic shared libraries are called on FreeBSD)?

time.time is supposed to be very high resolution, BTW, as internally it calls gettimeofday (well, in a properly built Python, anyway) -- what resolution do you observe for it on your system?

Edit: here's wat.c, a BSD-specific extension (tested on my Mac only -- sorry but I have no other BSD flavor at hand right know) to work around this apparent FreeBSD port problem:

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

And here's the setup.py to put in the same directory:

from distutils.core import setup, Extension

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

The URL is correct, so you can also get these two files zipped up here.

To build & install this extension, python setup.py install (if you have permission to write in your Python's installation) or python setup.py build_ext -i to write wat.so in the very directory in which you put the sources (and then manually move it wherever you prefer to have it, but first try it out e.g. with python -c'import wat; print repr(wat.time())' in the same directory in which you've built it).

Please let me know how it works on FreeBSD (or any other Unix flavor with gettimeofday!-) -- if the C compiler complains about gettimeofday, you may be on a system which doesn't want to see its second argument, try without it!-).

梦里的微风 2024-08-02 20:41:03

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

我希望这可以澄清问题。

time.clock() returns the processor time. That is, how much time the current process has used on the processor. So if you have a Python script called "clock.py", that does import time;print time.clock() it will indeed print about exactly the same each time you run it, as a new process is started each time.

Here is a python console log that might explain it to you:

>>> 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

I hope this clarifies things.

兰花执着 2024-08-02 20:41:03

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

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

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

祝你好运!

time.clock() returns CPU time on UNIX systems, and wallclock time since program start on Windows. This is a very unfortunate insymmetry, in my opinion.

You can find the definition for time.time() in the Python sources here (link to Google Code Search). It seems to use the highest-resolution timer available, which according to a quick Googling is gettimeofday() on FreeBSD as well, and that should be in the microsecond accuracy class.

However, if you really need more accuracy, you could look into writing your own C module for really high-resolution timing (something that might just return the current microsecond count, maybe!). Pyrex makes Python extension writing very effortless, and SWIG is the other common choice. (Though really, if you want to shave as many microseconds off your timer accuracy, just write it as a pure C Python extension yourself.) Ctypes is also an option, but probably rather slow.

Best of luck!

巴黎夜雨 2024-08-02 20:41:03

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

 ((double)clock()) / CLOCKS_PER_SEC

Why do you think time.time() has bad resolution? 它使用gettimeofday,它反过来读取硬件时钟,它具有非常好的分辨率。

time.clock() is implemented to return a double value resulting from

 ((double)clock()) / CLOCKS_PER_SEC

Why do you think time.time() has bad resolution? It uses gettimeofday, which in turn reads the hardware clock, which has very good resolution.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文