Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/312.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何防止Cython中的Python交互_Python_Cython - Fatal编程技术网

如何防止Cython中的Python交互

如何防止Cython中的Python交互,python,cython,Python,Cython,我有一个简单的Cython函数,它获取memoryview的长度: cdef int get_length(int[:] a): return len(a) 我使用annotate=True指令编译代码,让我看看Cython在哪里有一些Python交互 生成的html包含以下文本,用于返回len(a)行: __pyx_t_1 = __Pyx_MemoryView_Len(__pyx_v_a); __pyx_r = __pyx_t_1; goto __pyx_L0; 这种

我有一个简单的Cython函数,它获取memoryview的长度:

cdef int get_length(int[:] a):
    return len(a)
我使用
annotate=True
指令编译代码,让我看看Cython在哪里有一些Python交互

生成的html包含以下文本,用于
返回len(a)
行:

  __pyx_t_1 = __Pyx_MemoryView_Len(__pyx_v_a); 
  __pyx_r = __pyx_t_1;
  goto __pyx_L0;

这种Python交互应该很慢。我有没有办法阻止Python交互?我试过
a.shape[0]
,但没有效果。

你不必担心,
\u Pyx\u MemoryView\u Len
速度很快,因为:

这一行的颜色不是黄色而是淡黄色-这主要意味着它不会产生纯C代码,而是使用了一些
\u Pyx\u XXX
功能,这通常对性能一点也不坏

没有Python交互-在C预处理器传递之后,C编译器将看到它,就好像您编写了:

return a.shape[0]
顺便说一下,这会引出一条白线

如果您还对多维memview的大小感兴趣,那么可能值得一读


注释将函数的定义显示为黄线。然而,只有模块加载时的成本(并且只支付一次,而不是每次调用函数时)才是“黄色”的原因

看一下由此产生的C代码:

static int __pyx_f_9my_module_get_length(__Pyx_memviewslice __pyx_v_a) {
  int __pyx_r;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("get_length", 0);

  /* "my_module.pyx":5
 * 
 * cdef int get_length(int[:] a):
 *     return a.shape[0]             # <<<<<<<<<<<<<<
 */
  __pyx_r = (__pyx_v_a.shape[0]);
  goto __pyx_L0;

  /* "my_module.pyx":4
 *     return 3. * a
 * 
 * cdef int get_length(int[:] a):             # <<<<<<<<<<<<<<
 *     return a.shape[0]
 */

  /* function exit code */
  __pyx_L0:;
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}

但是,此代码是
\uuupyx\upymod\uexec\uuxxxxx
/
PyInit\uuxxxxx
的一部分,在加载模块时只调用一次。事实上,我不确定这与
get_length
有什么关系,也不知道为什么需要这样做,但因为成本太低,我一直都不想知道。

谢谢您的详细解释。为什么只有在加载模块时才有成本?“我不是一个C语言程序员。”我补充了一些解释
static int __pyx_f_9my_module_get_length(__Pyx_memviewslice __pyx_v_a) {
  int __pyx_r;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("get_length", 0);

  /* "my_module.pyx":5
 * 
 * cdef int get_length(int[:] a):
 *     return a.shape[0]             # <<<<<<<<<<<<<<
 */
  __pyx_r = (__pyx_v_a.shape[0]);
  goto __pyx_L0;

  /* "my_module.pyx":4
 *     return 3. * a
 * 
 * cdef int get_length(int[:] a):             # <<<<<<<<<<<<<<
 *     return a.shape[0]
 */

  /* function exit code */
  __pyx_L0:;
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}
/* … */
  __pyx_t_1 = __Pyx_PyDict_NewPresized(0); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 1, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  if (PyDict_SetItem(__pyx_d, __pyx_n_s_test, __pyx_t_1) < 0) __PYX_ERR(1, 1, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;