Вопрос

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

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

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

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

Это было полезно?

Решение

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

Я надеюсь, что это кое-что прояснит.

Другие советы

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

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

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

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

Желаю удачи!

time.clock() реализован для возврата двойного значения, полученного в результате

 ((double)clock()) / CLOCKS_PER_SEC

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top