问题
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.
回答1:
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.
回答2:
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 = "aleaxit@gmail.com",
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!-).
回答3:
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!
回答4:
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.
来源:https://stackoverflow.com/questions/1110063/python-clock-function-on-freebsd