[英]Cython efficient cycle 'for' for a given list instead of range(N)
我正在使用cython(python 2.7)进行编码,并且正在处理“ for”循环。 只要我for i in range(N)
使用标准,我就会得到一个很酷的代码:cythonized code.html
上没有黄色警告。
当我创建一个整数列表(因为range(N)是,不是吗?)时,例如:
cdef long [:] lista = np.array(list(nx.node_connected_component(Graph, v)))
这给出了图Graph
中v
的连接组件中节点的所有索引的列表。 当我尝试for i in lista:
定义时,出现黄色警告:
__pyx_t_1 = __pyx_memoryview_fromslice(__pyx_v_lista, 1, (PyObject *(*)(char *)) __pyx_memview_get_long, (int (*)(char *, PyObject *)) __pyx_memview_set_long, 0);; if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 151, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_1);
if (likely(PyList_CheckExact(__pyx_t_1)) || PyTuple_CheckExact(__pyx_t_1)) {
__pyx_t_6 = __pyx_t_1; __Pyx_INCREF(__pyx_t_6); __pyx_t_15 = 0;
__pyx_t_17 = NULL;
} else {
__pyx_t_15 = -1; __pyx_t_6 = PyObject_GetIter(__pyx_t_1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 151, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_6);
__pyx_t_17 = Py_TYPE(__pyx_t_6)->tp_iternext; if (unlikely(!__pyx_t_17)) __PYX_ERR(0, 151, __pyx_L1_error)
}
__Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
for (;;) {
if (likely(!__pyx_t_17)) {
if (likely(PyList_CheckExact(__pyx_t_6))) {
if (__pyx_t_15 >= PyList_GET_SIZE(__pyx_t_6)) break;
#if CYTHON_COMPILING_IN_CPYTHON
__pyx_t_1 = PyList_GET_ITEM(__pyx_t_6, __pyx_t_15); __Pyx_INCREF(__pyx_t_1); __pyx_t_15++; if (unlikely(0 < 0)) __PYX_ERR(0, 151, __pyx_L1_error)
#else
__pyx_t_1 = PySequence_ITEM(__pyx_t_6, __pyx_t_15); __pyx_t_15++; if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 151, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_1);
#endif
} else {
if (__pyx_t_15 >= PyTuple_GET_SIZE(__pyx_t_6)) break;
#if CYTHON_COMPILING_IN_CPYTHON
__pyx_t_1 = PyTuple_GET_ITEM(__pyx_t_6, __pyx_t_15); __Pyx_INCREF(__pyx_t_1); __pyx_t_15++; if (unlikely(0 < 0)) __PYX_ERR(0, 151, __pyx_L1_error)
#else
__pyx_t_1 = PySequence_ITEM(__pyx_t_6, __pyx_t_15); __pyx_t_15++; if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 151, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_1);
#endif
}
} else {
__pyx_t_1 = __pyx_t_17(__pyx_t_6);
if (unlikely(!__pyx_t_1)) {
PyObject* exc_type = PyErr_Occurred();
if (exc_type) {
if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
else __PYX_ERR(0, 151, __pyx_L1_error)
}
break;
}
__Pyx_GOTREF(__pyx_t_1);
}
__pyx_t_2 = __Pyx_PyInt_As_int(__pyx_t_1); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 151, __pyx_L1_error)
__Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
__pyx_v_i = __pyx_t_2;
/* … */
}
__Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
该代码显然可以工作,但是由于我需要经常使用这些循环,所以我现在想知道如何正确实现它们。
lista
的正确分配是哪一个?
最好只按索引遍历
cdef Py_ssize_t i
cdef long val
with cython.boundscheck(False): # these two lines are optional but may increase speed
with cython.wraparound(False):
for i in range(lista.shape[0]):
val = lista[i]
您可能要进行的另一种优化是将lista
定义为
cdef long [::1] lista
指出它在内存中是连续的。
(我对这个问题的初步np.array(list(nx.node_connected_component(Graph, v)))
使我认为这是关于从set
进行转换的: np.array(list(nx.node_connected_component(Graph, v)))
。我不认为这是您要的内容,但如果是这样,我看不到加快这条线的方法。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.