<p>我对您的代码做了一些工作,这里是基准测试。
瓶颈在于阶乘计算</p>
<pre><code> ================== PerfTool ==================
task |aver(s) |sum(s) |count |std
main loop | 0.134| 10.712| 80| 0.101
+-second loop | 0.134| 10.712| 80| 0.101
+-A | 0.000| 0.245| 6560| 0.000
+-B | 0.001| 5.648| 6560| 0.001
+-C | 0.000| 0.541| 6560| 0.000
+-D | 0.000| 1.505| 6560| 0.000
+-E | 0.000| 1.769| 6560| 0.000
+-F | 0.000| 0.867| 6560| 0.000
mx creation | 0.000| 0.000| 1| 0.000
preparation | 0.000| 0.000| 1| 0.000
overall | 0.03| 10.71| 39522|-
</code></pre>
<p><strong>B</strong>和<strong>C</strong>哨兵是:</p>
<pre><code> with PerfTool('B'):
for p in range(p_mn,n+1,1):
Cai_pmn = math.factorial(n) * ((-1)**(n + p)) / (math.factorial(p) * math.factorial(n - p)) * math.factorial(2 * p)/math.factorial(2 * p - np.abs(m) - n)
A_mn = A_mn + Cai_pmn * (np.cos(matrix_a))**(2 * p - np.abs(m) - n)
B_mn = B_mn + (2 * p - np.abs(m) - n) * Cai_pmn * (np.cos(matrix_a))**(np.abs(2 * p - np.abs(m) - n - 1))
with PerfTool('C'):
A_mn = A_mn / (2**n * math.factorial(n))
B_mn = B_mn / (2**n * math.factorial(n))
</code></pre>
<p>正如您所看到的,大部分时间都花在B上,因此我添加了一种缓存,如下所示:</p>
<pre><code> rng = np.arange(1,nmax+1,1)
cache = dict(zip(rng,factorial(rng)))
def get_factorial(w,cache=cache):
if w not in cache:
cache[w] = math.factorial(w)
return cache[w]
</code></pre>
<p>要使用而不是math.factorial,可以避免重新计算相同的值</p>
<p>最后,<strong>B</strong>被重构为<strong>B_-vec</strong>,这就是邪恶的根源!
我已经将代码标记为B_vec_slow,2行<em>占用了大部分时间</em></p>
<pre><code> with PerfTool('B_vec'):
prng = np.arange(p_mn, n+1)
Cai_pmn_vec = get_factorial(n) * ((-1)**(n + prng)) / (factorial(prng) * factorial(n - prng)) * factorial(2 * prng)/factorial(2 * prng - np.abs(m) - n)
with PerfTool('B_vec_slow'):
A_mn_vec = Cai_pmn_vec*np.power(cos_matrix_a[:,np.newaxis],2 * prng - np.abs(m) - n)
B_mn_vec = (2 * prng - np.abs(m) - n) * Cai_pmn_vec * np.power(cos_matrix_a[:,np.newaxis], np.abs(2 * prng - np.abs(m) - n - 1))
A_mn = np.sum(A_mn_vec,axis=1)
B_mn = np.sum(B_mn_vec,axis=1)
</code></pre>
<p>结果是:</p>
<pre><code>================== PerfTool ==================
task |aver(s) |sum(s) |count |std
main loop | 0.072| 5.736| 80| 0.052
+-second loop | 0.072| 5.735| 80| 0.052
+-A | 0.000| 0.194| 6560| 0.000
+-B_vec | 0.001| 3.490| 6560| 0.000
+-B_vec_slow | 0.000| 2.987| 6560| 0.000
+-C | 0.000| 0.126| 6560| 0.000
+-D | 0.000| 0.536| 6560| 0.000
+-E | 0.000| 0.768| 6560| 0.000
+-F | 0.000| 0.522| 6560| 0.000
preparation | 0.000| 0.000| 1| 0.000
mx creation | 0.000| 0.000| 1| 0.000
overall | 0.01| 5.74| 46082|-
</code></pre>
<p>如果你能在这两条线上工作,你可以期望在2/3秒内运行</p>
<p><em>这里</em>:优化的代码:<a href="https://www.codepile.net/pile/8oDyGp6Q" rel="nofollow noreferrer">https://www.codepile.net/pile/8oDyGp6Q</a></p>