Функция часов Python во FreeBSD - PullRequest
0 голосов
/ 10 июля 2009

Во время тестирования функции Pythons time.clock () во FreeBSD я заметил, что она всегда возвращает одно и то же значение, около 0,156

Функция time.time () работает нормально, но мне нужно что-то с чуть более высоким разрешением.

Кто-нибудь имеет функцию C, к которой он привязан, и есть ли альтернативный таймер высокого разрешения?

Я не профилирую, поэтому модуль TimeIt здесь не совсем подходит.

Ответы [ 4 ]

3 голосов
/ 10 июля 2009

Python time.clock вызывает функцию C clock (3) - man clock должен подтвердить, что она должна работать на BSD, поэтому я не знаю, почему она не работает для вас. Возможно, вы можете попытаться обойти эту явную ошибку в вашем порту Python, используя ctypes для непосредственного вызова функции clock из библиотеки system C (если вы указали библиотеку как .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 = "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 (или любом другом варианте Unix с gettimeofday! -) - если компилятор C жалуется на gettimeofday, возможно, вы находитесь в системе, которая не хочет видеть второй аргумент, попробуйте без него! -).

1 голос
/ 10 июля 2009

time.clock () возвращает время процессора. То есть сколько времени текущий процесс использовал на процессоре. Поэтому, если у вас есть скрипт Python с именем «clock.py», который выполняет 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

Надеюсь, это прояснит ситуацию.

1 голос
/ 10 июля 2009

time.clock() возвращает время процессора в системах UNIX и время настенных часов с момента запуска программы в Windows. Это очень неудачная асимметрия, на мой взгляд.

Вы можете найти определение time.time() в источниках Python здесь (ссылка на Google Code Search). Кажется, он использует таймер с самым высоким разрешением, который, согласно быстрому поиску, также равен gettimeofday() на FreeBSD, и это должно быть в классе микросекундной точности.

Однако, если вам действительно нужно больше точности, вы можете заняться написанием своего собственного модуля C для измерения времени с действительно высоким разрешением (что-то, что может просто вернуть текущий счетчик микросекунд, возможно!). Pyrex делает расширение Python написанным очень легко, а SWIG является другим распространенным выбором. (Хотя на самом деле, если вы хотите снизить точность таймера на столько же микросекунд, просто напишите это как расширение на чистом языке Python.) Ctypes также является опцией, но, вероятно, довольно медленной.

Удачи!

0 голосов
/ 10 июля 2009

time.clock () реализован так, чтобы возвращать двойное значение, полученное из

 ((double)clock()) / CLOCKS_PER_SEC

Как вы думаете, почему у time.time () плохое разрешение? Он использует gettimeofday, который, в свою очередь, читает аппаратные часы с очень хорошим разрешением.

...