我正在使用以下代碼,其形式未更改,但內容有所更改:
import numpy as np
import matplotlib.pyplot as plt
import random
from random import seed
from random import randint
import math
from math import *
from random import *
import statistics
from statistics import *
n=1000
T_plot=[0];
X_relm=[0];
class Objs:
def __init__(self, xIn, yIn, color):
self.xIn= xIn
self.yIn = yIn
self.color = color
def yfT(self, t):
return self.yIn*t self.yIn*t
def xfT(self, t):
return self.xIn*t-self.yIn*t
xi=np.random.uniform(0,1,n);
yi=np.random.uniform(0,1,n);
O1 = [Objs(xIn = i, yIn = j, color = choice(["Black", "White"])) for i,j
in zip(xi,yi)]
X=sorted(O1,key=lambda x:x.xIn)
dt=1/(2*n)
T=20
iter=40000
Black=[]
White=[]
Xrelm=[]
for i in range(1,iter 1):
t=i*dt
for j in range(n-1):
check=X[j].xfT(t)-X[j 1].xfT(t);
if check<0:
X[j],X[j 1]=X[j 1],X[j]
if check<-10:
X[j].color,X[j 1].color=X[j 1].color,X[j].color
if X[j].color=="Black":
Black.append(X[j].xfT(t))
else:
White.append(X[j].xfT(t))
Xrel=mean(Black)-mean(White)
Xrelm.append(Xrel)
plot1=plt.figure(1);
plt.plot(T_plot,Xrelm);
plt.xlabel("time")
plt.ylabel("Relative ")
它繼續運行(我把它放了 10 個小時)而沒有給出一些引數的輸出,只是因為我猜它太大了。我知道我的代碼沒有完全錯誤(從某種意義上說,即使錯誤也應該給出一些東西),因為它確實提供了更少的時間步長和其他引數的輸出。
因此,我專注于嘗試優化我的代碼,以減少運行時間。現在,這是編碼人員的例行任務,但我是新手,我正在編碼只是因為模擬將有助于我的領域。因此,一般來說,任何一般性質的輸入都可以提供有關如何使代碼更快的見解,我們將不勝感激。
除此之外,我想問一下為內部回圈定義一個先驗函式是否會節省任何時間。
我認為它不應該節省任何時間,因為我正在做同樣的事情,但我不確定它是否可以。如果沒有,任何關于如何以更有效的方式處理嵌套回圈以及一般性質的方法的見解都會受到贊賞。
(我已盡量縮短代碼,但仍然不錯過相關資訊)
uj5u.com熱心網友回復:
您的代碼中有幾個問題:
- 平均值是根據不斷增長的陣列從頭開始重新計算的。因此,復雜度
mean(Black)-mean(White)
與元素的數量成二次方。 - 該
mean
功能效率不高。使用基本sum
和除法要快得多。事實上,在我的機器上,手動平均要快 25~30 倍。 - CPython 解釋器非常慢,因此您應該盡可能避免使用回圈(OOP 代碼也無濟于事)。如果這是不可能的并且您的計算成本很高,那么請考慮使用本機編譯的代碼。您可以使用 PyPy、Numba 或 Cython 等工具,也可以使用 C 重寫部分內容。
- 請注意,字串通常很慢,這里沒有理由使用它們。考慮改用列舉(即整數)。
這是修復前兩點的代碼:
dt = 1/(2*n)
T = 20
iter = 40000
Black = []
White = []
Xrelm = []
cur1, cur2 = 0, 0
sum1, sum2 = 0.0, 0.0
for i in range(1,iter 1):
t = i*dt
for j in range(n-1):
check = X[j].xfT(t) - X[j 1].xfT(t)
if check < 0:
X[j],X[j 1] = X[j 1],X[j]
if check < -10:
X[j].color, X[j 1].color = X[j 1].color, X[j].color
if X[j].color == "Black":
Black.append(X[j].xfT(t))
else:
White.append(X[j].xfT(t))
delta1, delta2 = sum(Black[cur1:]), sum(White[cur2:])
sum1, sum2 = sum1 delta1, sum2 delta2
cur1, cur2 = len(Black), len(White)
Xrel = sum1/cur1 - sum2/cur2
Xrelm.append(Xrel)
如果您以后不使用它們,請考慮將Black
和重置為空串列。White
這快了幾百倍。現在需要 2 分鐘,而不是初始代碼 > 20h(估計)。
請注意,這里使用編譯代碼應該至少快 10 倍,因此執行時間應該不超過幾十秒。
uj5u.com熱心網友回復:
正如前面的評論中提到的,這個回答有點過于寬泛。
為了顯示; 您的迭代本身不會花費很長時間:
import time
start = time.time()
for i in range(10000):
for j in range(10000):
pass
end = time.time()
print (end-start)
在我不太出色的機器上,大約需要 2 秒才能完成。
所以回圈部分只是你 10 小時以上運行時間的一小部分。
你在回圈中所做的事情的細節是關鍵。
雖然非常基本,但我在上面的代碼中展示的方法可以應用于您現有的代碼,以確定哪些位的性能最低,然后提出一個新問題,并提供一些更具體、可操作的細節。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/481547.html