On Sat, Apr 4, 2009 at 9:28 PM, Vic Kelson <[email protected]> wrote:
> Another question: If I need the constant pi, and I use math.pi or numpy.pi
> in a C function (or a C method of a C class), does it add an inefficiency
> (Python lookup)?
> Just wondering...
Yes. Use Cython's annotate option (or just reading the output) shows
that the "k=math.pi" code in the following:
import math
cdef foo():
cdef double k
k = math.pi
generates the following C:
__pyx_1 = __Pyx_GetName(__pyx_m, __pyx_kp_math); if
(unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 9;
__pyx_clineno = __LINE__; goto __pyx_L1_error;}
__pyx_2 = PyObject_GetAttr(__pyx_1, __pyx_kp_pi); if
(unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 9;
__pyx_clineno = __LINE__; goto __pyx_L1_error;}
Py_DECREF(__pyx_1); __pyx_1 = 0;
__pyx_3 = __pyx_PyFloat_AsDouble(__pyx_2); if
(unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0];
__pyx_lineno = 9; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
Py_DECREF(__pyx_2); __pyx_2 = 0;
__pyx_v_k = __pyx_3;
Timing the following two code snippets shows that using math.pi
instead of a hardcoded double constant for pi can easily slow down a
function by a *factor of 100*.
import math
def foo(int n):
cdef double k = 0
cdef int i
for i in range(n):
k += math.pi
return k
import math
def foo2(int n):
cdef double k=0, pi = 3.14159265358979
cdef int i
for i in range(n):
k += pi
return k
sage: timeit('foo(10**5)')
25 loops, best of 3: 12.5 ms per loop
sage: timeit('foo2(10**5)')
625 loops, best of 3: 114 µs per loop
sage: 12.5/0.114
109.649122807018
If you want to write very fast code, you might learn and use the -a
option to Cython.
William
-- William
_______________________________________________
Cython-dev mailing list
[email protected]
http://codespeak.net/mailman/listinfo/cython-dev