Last active
March 26, 2020 06:04
-
-
Save will-ca/35dc57f07a88de947f31023432158d12 to your computer and use it in GitHub Desktop.
Quick test of the speed difference between `object` and `PyObject*` for frequently re-created `cdef` attributes.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# cython: language_level=3 | |
import cython, random, array, timeit | |
test_floats = [*range(10000)] | |
test_tuples = [(i,) for i in range(10000)] | |
test_switches = array.array('i', [random.randint(0,1) for i in range(10000)]) | |
class addend_ptrwrapper: | |
def __cinit__(self, obj, nonzero:cython.bint=True): | |
self.obj = cython.cast(cython.pointer(PyObject), obj) | |
self.nonzero = nonzero | |
def __init__(self, obj, nonzero:cython.bint=True): | |
if not cython.compiled: | |
addend_ptrwrapper.__cinit__(self, obj, nonzero=nonzero) | |
def add_ptrwrapped_floats(seq): | |
s = 0.0 | |
for i in seq: | |
if i.nonzero: | |
s += cython.cast(object, i.obj) | |
return s | |
def add_ptrwrapped_tuples(seq): | |
s = 0 | |
for i in seq: | |
if i.nonzero: | |
s += len(cython.cast(object, i.obj)) | |
return s | |
class addend_objwrapper: | |
def __cinit__(self, obj, nonzero:cython.bint=True): | |
self.obj = obj | |
self.nonzero = nonzero | |
def __init__(self, obj, nonzero:cython.bint=True): | |
if not cython.compiled: | |
addend_objwrapper.__cinit__(self, obj, nonzero=nonzero) | |
def add_objwrapped_floats(seq): | |
s = 0.0 | |
for i in seq: | |
if i.nonzero: | |
s += i.obj | |
return s | |
def add_objwrapped_tuples(seq): | |
s = 0 | |
for i in seq: | |
if i.nonzero: | |
s += len(i.obj) | |
return s | |
def get_ptrtest_seq(seq, getseq=True): | |
outseq = [] | |
i = 0 | |
a = cython.cast(array.array, test_switches) | |
for obj in seq: | |
w = addend_ptrwrapper.__new__(addend_ptrwrapper, obj, a.data.as_ints[i]) | |
if getseq: | |
outseq.append(w) | |
i += 1 | |
return outseq | |
def get_objtest_seq(seq, getseq=True): | |
outseq = [] | |
i = 0 | |
a = cython.cast(array.array, test_switches) | |
for obj in seq: | |
w = addend_objwrapper.__new__(addend_objwrapper, obj, a.data.as_ints[i]) | |
if getseq: | |
outseq.append(w) | |
i += 1 | |
return outseq | |
def dotime(code): | |
return min(timeit.repeat(code, globals=globals(), number=1, repeat=1000)) | |
def timeruns(): | |
print("Wrapping floats with pointers:") | |
print(dotime('get_ptrtest_seq(test_floats, False)')) | |
print("Wrapping floats with objects:") | |
print(dotime('get_objtest_seq(test_floats, False)')) | |
print() | |
print("Wrapping tuples with pointers:") | |
print(dotime('get_ptrtest_seq(test_tuples, False)')) | |
print("Wrapping tuples with objects:") | |
print(dotime('get_objtest_seq(test_tuples, False)')) | |
print() | |
print("Wrapping and summing floats with pointers:") | |
print(dotime('add_ptrwrapped_floats(get_ptrtest_seq(test_floats))')) | |
print("Wrapping and summing floats with objects:") | |
print(dotime('add_objwrapped_floats(get_objtest_seq(test_floats))')) | |
print() | |
print("Wrapping and summing tuple lengths with pointers:") | |
print(dotime('add_ptrwrapped_tuples(get_ptrtest_seq(test_tuples))')) | |
print("Wrapping and summing tuple lengths with objects:") | |
print(dotime('add_objwrapped_tuples(get_objtest_seq(test_tuples))')) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment