Description
In many cases Cython cannot infer the type of the looping variable (for example, when the looping variable is used as an index). In these cases, Cython will run the loop as a Python loop. Adding type identifiers allows Cython to run the loop as a C loop, which is much faster. With methods that are called often (for example, getVars
inside a pricer), this could make a noticeable difference. We just need to be careful about potential integer overflows.
In getVars
we have the following code:
for i in range(_nvars):
ptr = <size_t>(_vars[i])
# check whether the corresponding variable exists already
if ptr in self._modelvars:
vars.append(self._modelvars[ptr])
else:
# create a new variable
var = Variable.create(_vars[i])
assert var.ptr() == ptr
self._modelvars[ptr] = var
vars.append(var)
Simply adding cdef int i
at the beginning of the code would achieve the desired result.
Probably less importantly, PySCIPOpt's code defines functions using the def
command, meaning that it's creating a Python function. Calling these functions incurs some overhead. Using cpdef
allows the functions to be used as Python functions from the outside but with the speed of C functions. We need to properly type the arguments of the function, but we should already be doing that (see PR #730). (A caveat of cpdef
is that the return type and the argument types must be valid for both Python and C)
The impact shouldn't be very big, since once we're inside the functions, both are the same, but there is no reason not to do it really, and it might have some marginal impact when the user has a loop that calls a function often.