Commit 6b1193e9 authored by Stefan Behnel's avatar Stefan Behnel

reduce call overhead of functions with fused types (especially when using numpy arrays)

parent 9db5c060
......@@ -453,11 +453,7 @@ class FusedCFuncDefNode(StatListNode):
pyx_code.imports.put_chunk(
u"""
cdef type ndarray
try:
import numpy
ndarray = numpy.ndarray
except (ImportError, AttributeError, TypeError):
ndarray = None
ndarray = __Pyx_ImportNumPyArrayTypeIfAvailable()
""")
seen_int_dtypes = set()
......@@ -514,7 +510,7 @@ class FusedCFuncDefNode(StatListNode):
# PROCESSING ARGUMENT {{arg_tuple_idx}}
if {{arg_tuple_idx}} < len(<tuple>args):
arg = (<tuple>args)[{{arg_tuple_idx}}]
elif '{{arg.name}}' in <dict>kwargs:
elif kwargs is not None and '{{arg.name}}' in <dict>kwargs:
arg = (<dict>kwargs)['{{arg.name}}']
else:
{{if arg.default}}
......@@ -549,6 +545,7 @@ class FusedCFuncDefNode(StatListNode):
u"""
cdef extern from *:
void __pyx_PyErr_Clear "PyErr_Clear" ()
type __Pyx_ImportNumPyArrayTypeIfAvailable()
""")
decl_code.indent()
......@@ -564,8 +561,8 @@ class FusedCFuncDefNode(StatListNode):
dest_sig = [None] * {{n_fused}}
if kwargs is None:
kwargs = {}
if kwargs is not None and not kwargs:
kwargs = None
cdef Py_ssize_t i
......@@ -623,13 +620,16 @@ class FusedCFuncDefNode(StatListNode):
if all_buffer_types:
self._buffer_declarations(pyx_code, decl_code, all_buffer_types)
env.use_utility_code(Code.UtilityCode.load_cached("Import", "ImportExport.c"))
env.use_utility_code(Code.UtilityCode.load_cached("ImportNumPyArray", "ImportExport.c"))
pyx_code.put_chunk(
u"""
candidates = []
for sig in <dict>signatures:
match_found = False
for src_type, dst_type in zip(sig.strip('()').split('|'), dest_sig):
src_sig = sig.strip('()').split('|')
for i in range(len(dest_sig)):
src_type, dst_type = src_sig[i], dest_sig[i]
if dst_type is not None:
if src_type == dst_type:
match_found = True
......
......@@ -661,3 +661,39 @@ bad:
Py_XDECREF(ob);
return NULL;
}
/////////////// ImportNumPyArray.proto ///////////////
static PyObject* __Pyx_ImportNumPyArrayTypeIfAvailable(void); /*proto*/
/////////////// ImportNumPyArray.cleanup ///////////////
Py_CLEAR(__pyx_numpy_ndarray);
/////////////// ImportNumPyArray ///////////////
//@requires: ImportExport.c::Import
static PyObject *__pyx_numpy_ndarray = NULL;
static PyObject* __Pyx__ImportNumPyArray(void) {
PyObject *numpy_module, *ndarray_object = NULL;
numpy_module = __Pyx_Import(PYIDENT("numpy"), NULL, 0);
if (likely(numpy_module)) {
ndarray_object = PyObject_GetAttrString(numpy_module, "ndarray");
if (unlikely(!ndarray_object)) {
PyErr_Clear();
}
}
if (unlikely(!ndarray_object || !PyObject_TypeCheck(ndarray_object, &PyType_Type))) {
Py_XDECREF(ndarray_object);
Py_INCREF(Py_None);
ndarray_object = Py_None;
}
return ndarray_object;
}
static CYTHON_INLINE PyObject* __Pyx_ImportNumPyArrayTypeIfAvailable(void) {
if (unlikely(!__pyx_numpy_ndarray)) {
__pyx_numpy_ndarray = __Pyx__ImportNumPyArray();
}
return __pyx_numpy_ndarray;
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment