我已經繼承了Visual Studio/VB.Net數值模擬項目,其計算可能效率低下。分析表明該函數被稱爲很多(100萬次以上),並且在該函數中花費了總體計算的大約50%。下面是有問題的部分優化劃分/指數計算
結果=(A *(E^C))/(d^C * B)(其中,AC是局部雙變量和d &Ë全局雙變量)
結果然後相比可能有更多的改進以及閾值,但我會離開他們的一天
任何想法或幫助將不勝感激
史蒂夫
我已經繼承了Visual Studio/VB.Net數值模擬項目,其計算可能效率低下。分析表明該函數被稱爲很多(100萬次以上),並且在該函數中花費了總體計算的大約50%。下面是有問題的部分優化劃分/指數計算
結果=(A *(E^C))/(d^C * B)(其中,AC是局部雙變量和d &Ë全局雙變量)
結果然後相比可能有更多的改進以及閾值,但我會離開他們的一天
任何想法或幫助將不勝感激
史蒂夫
一個簡單的加速是
Result = (A/B) * (E/D)^C
至少你正在做一個較少的指數。 根據C是什麼,可能會有更快的方法。就像C是一個小整數一樣。
編輯: 增加證據證明這是更快
public static void main(String[] args) {
StopWatch sw = new StopWatch();
float e = 1.123F;
float d = 4.456F;
float c = 453;
sw.start();
int max = 5000;
double result = 0;
for (int a = 1; a < max; a++) {
for (float b = 1; b < max; b++) {
result = (a * (Math.pow(e, c)))/(Math.pow(d, c) * b);
}
}
sw.split();
System.out.println("slow: " + sw.getSplitTime() + " result: " + result);
sw.stop();
sw.reset();
sw.start();
result = 0;
for (int a = 1; a < max; a++) {
for (float b = 1; b < max; b++) {
result = a/b * Math.pow(e/d, c);
}
}
sw.split();
System.out.println("fast: " + sw.getSplitTime() + " result: " + result);
sw.stop();
sw.reset();
}
這是輸出
slow: 26062 result: 7.077390271736578E-272
fast: 12661 result: 7.077392136525382E-272
有一個在數字有些歪斜。我會認爲更快的版本更準確(但這只是一種感覺,因爲我不知道爲什麼)。
指數運算符(Math.Pow)不是很快,沒有專門的CPU指令來計算它。你提到D和E是全局變量。如果你能夠隔離它們的變化,那麼它可以讓你更快地獲得希望。重寫使用對數方程:
log(r) = log((a x e^c)/(b x d^c))
= log(a x e^c) - log (b x d^c)
= log(a) + log(e^c) - log(b) - log(d^c)
= log(a) + c*log(e) - log(b) - c*log(d)
= log(a) - log(b) + c x (log(e) - log(d))
result = exp(r)
提供有這一功能來計算結果:
Function calculate(ByVal a As Double, ByVal b As Double, ByVal c As Double, ByVal d As Double, ByVal e As Double) As Double
Dim logRes = Math.Log(a) - Math.Log(b) + c * (Math.Log(e) - Math.Log(d))
Return Math.Exp(logRes)
End Function
我用秒錶計時類,它是完全一樣快,你的原始表達式。當然不是巧合。您可以通過某種方式預先計算Math.Log(e) - Math.Log(d)項。
做好分析。我也會在每次通話時檢查A-C是不同的。換句話說,有可能調用者實際上一遍又一遍地計算相同的值嗎?如果是這樣,請更改它以緩存答案。
對於Math.Floor()函數,請訪問: http://bitsbyta.blogspot.com/2010/12/math-floor-function-vbnet.html
在vb.net數學庫的所有功能,請訪問: http://www.bitsbyta.blogspot.com/
+1用於分析由 「全球」 問 – 2010-04-15 20:02:59
之前你暗示他們從不改變?你可能可以設置「F = E/D」一次,然後按照下面我的回答中所提到的做F^C而不是「(E/D)^ C」。 – mlathe 2010-04-15 20:12:09