<p>一种实现您想要实现的方法是将<em>Runge-Kutta</em>方案的系数设置为全局变量,这样就可以使用静态数组。这很快,但肯定很难看</p>
<p><strong>丑陋的解决方案</strong>:</p>
<pre><code>cdef int numStages = 3
# Using the pointer notation you can set a static array
# as well as its elements in one go
cdef double* coeffs = [0.,0.,1.3]
# You can always change the coefficients further as you wish
def RungeKutta_StaticArrayGlobal():
# Do stuff
# Just to check
return numStages
</code></pre>
<p>更好的解决方案是定义一个<code>cython</code>类,其成员是<em>Runge-Kutta</em>系数</p>
<p><strong>优雅的解决方案</strong>:</p>
^{pr2}$
<p>关于设置元素的问题,让我们使用<code>calloc</code>而不是<code>malloc</code>来修改您自己的代码</p>
<p><strong>动态分配的版本</strong>:</p>
<pre><code>from libc.stdlib cimport calloc, free
ctypedef struct RKHelper:
int numStages
double* coeffs
def RungeKutta_DynamicArray():
cdef:
RKHelper firstRKMethod
firstRKMethod.numStages = 3
# Use calloc instead, it zero initialises the buffer, so you don't
# need to set the elements to zero within a loop
firstRKMethod.coeffs = <double*> calloc(firstRKMethod.numStages,sizeof(double))
# Set non-zero elements
firstRKMethod.coeffs[2] = 1.3
free(firstRKMethod.coeffs)
# Just to check
return firstRKMethod.numStages
</code></pre>
<p>让我们做一个有点荒谬的基准测试,来验证前两个例子中的数组是真正静态的(即没有运行时开销)</p>
<pre><code>In[1]: print(RungeKutta_DynamicArray())
3
In[2]: print(RungeKutta_StaticArray())
3
In[3]: obj = RungeKutta_StaticArrayClass()
In[4]: print(obj.GetnumStages())
3
In[5]: %timeit RungeKutta_DynamicArray()
10000000 loops, best of 3: 65.2 ns per loop
In[6]: %timeit RungeKutta_StaticArray()
10000000 loops, best of 3: 25.2 ns per loop
In[6]: %timeit RungeKutta_StaticArrayClass()
10000000 loops, best of 3: 49.6 ns per loop
</code></pre>
<p><code>RungeKutta_StaticArray</code>基本上有接近<code>no-op</code>的开销,这意味着数组分配没有运行时代价。您可以选择在此函数中声明<code>coeffs</code>,并且计时仍然相同。尽管使用其成员和构造函数设置类的开销,<code>RungeKutta_StaticArrayClass</code>仍然比动态分配的版本快。在</p>