Hi, I've search the archives for "short circuit" but did not find an answer.
So I am posting here.
Consider the following code (app.pyx):
from hashlib import sha1
cdef long expensive(long n, long k):
return long(sha1("%s:%s" % (n, k)).hexdigest()[:4], base=16) < 256
def test1(long n):
cdef long i, sum = 0
for i in range(n):
if expensive(i, 0) and expensive(i, 1): # short-circuit
sum += i
print sum
def test2(long n):
cdef long i, sum = 0
for i in range(n):
if expensive(i, 0): # nested-if
if expensive(i, 1):
sum += i
print sum
If this was pure Python, the performance of test1() and test2() would be the
same. However with Cython, test1() was twice as slow as test2().
Looking at app.c:
// if expensive(i, 0) and expensive(i, 1): # <<<<<<<<<<<<<<
if (__pyx_f_3app_expensive(__pyx_v_i, 0)) {
__pyx_t_2 = __pyx_f_3app_expensive(__pyx_v_i, 1);
} else {
__pyx_t_2 = __pyx_f_3app_expensive(__pyx_v_i, 0);
}
and
// if expensive(i, 0): # <<<<<<<<<<<<<<
__pyx_t_2 = __pyx_f_3app_expensive(__pyx_v_i, 0);
if (__pyx_t_2) {
// if expensive(i, 1): # <<<<<<<<<<<<<<
__pyx_t_2 = __pyx_f_3app_expensive(__pyx_v_i, 1);
if (__pyx_t_2) {
For the short-circuit version, the first test is sometimes evaluated twice.
For the nested-if version, it is evaluated exactly once.
Q: For the short-circuit, would the right behaviour be to store the result
of the first evaluation in a temporary variable instead?
I am new to Cython so pardon me if this is not the right place to ask. If a
patch is preferred, I can give it a try although I will take some time to
get familiar with the code.
Swee Heng
_______________________________________________
Cython-dev mailing list
[email protected]
http://codespeak.net/mailman/listinfo/cython-dev