<p>Kevin的解决方案是安全的,在更大的项目中应该是默认的,在这个项目中,您只是不知道您的函数将如何使用-因此,知道底层缓冲区是锁定的并且不能从另一个线程添加任何元素-这意味着我们传递给C例程的指针不会失效。在</p>
<p>如果函数具有带类型化内存视图的签名,甚至可以将其用于<code>array.array</code>和其他缓冲区,如numpy数组,例如:</p>
<pre><code>def Indexer(int[:] a):
</code></pre>
<p>这个答案试图回答这样一个问题:与使用<code>array.array</code>的不安全解决方案相比,类型化内存视图的开销是多少。为此,我们考虑以下示例,它更简单,但计时与原始函数相似:</p>
^{pr2}$
<p>现在:</p>
<pre><code>>>> import array
>>> a=array.array('i',range(1000))
>>> %timeit with_array(a)
160 ns ± 8.62 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
>>> %timeit direct_memview(a)
706 ns ± 22.7 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
>>> %timeit create_memview(a)
732 ns ± 19.3 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
</code></pre>
<p>所以基本上安全功能要慢4倍,很明显,在功能中做的工作越多,它就越少。在</p>
<p>另一个有趣的观察结果是:<a href="http://cython.readthedocs.io/en/latest/src/tutorial/array.html#safe-usage-with-memory-views" rel="nofollow noreferrer">documentation</a>将<code>direct_memory</code>称为无开销,而将{<cd4>}称为{<cd5>},但差别并不大(甚至不清楚是否存在!)与不安全的使用相比。在</p>
<p>如果我们将numpy数组传递给函数,则差别更大:</p>
<pre><code>>>> import numpy as np
>>> b=np.array(a, dtype=np.int32)
>>> %timeit direct_memview(b)
1.48 µs ± 64.6 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
>>> %timeit create_memview(b)
1.54 µs ± 28.6 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
</code></pre>
<p>numpy数组的开销是<code>array.array</code>的两倍,因此{<cd1>}似乎是轻量级任务的更好选择。在</p>
<p>我的结论是:使用不安全的版本可能是值得的,但是我只会在确定类型化内存视图的开销确实是瓶颈并且只有一个线程的情况下才会这么做。在</p>