2017-08-03 39 views
0

我複製了Moro的正態分佈的反累積函數的代碼,其中我添加了一個額外的錯誤處理來處理超出範圍(0,1)的輸入。當我用全部有效輸入測試代碼時,速度減慢了大約25%(6ns vs 8ns)。我很好奇,爲什麼即使不執行拋出異常仍然會降低性能?爲什麼添加潛在異常會導致性能下降,即使從未拋出?

碼反向功能:

double Inverse(double u) 
{ 
    double a[4] = { 
     2.50662823884, 
     -18.61500062529, 
     41.39119773534, 
     -25.44106049637 }; 

    double b[4] = { 
     -8.47351093090, 
     23.08336743743, 
     -21.06224101826, 
     3.13082909833 }; 
    double c[9] = { 
     0.3374754822726147, 
     0.9761690190917186, 
     0.1607979714918209, 
     0.0276438810333863, 
     0.0038405729373609, 
     0.0003951896511919, 
     0.0000321767881768, 
     0.0000002888167364, 
     0.0000003960315187 }; 

    // Assert(0 < u && u < 1); 
    if (u >= 1 || u <= 0){ 
     throw std::invalid_argument("Input out of range."); 
    } 

    /*return the inverse of cumulative normal distribution fonction*/ 

    double x, r; 

    x = u - 0.5; 
    if (fabs(x)<0.42) { 
     r = x*x; 
     r = x*(((a[3] * r + a[2])*r + a[1])*r + a[0])/((((b[3] * r + b[2])*r + b[1])*r + b[0])*r + 1.0); 
     return(r); 
    } 
    r = u; 
    if (x>0.0) r = 1 - u; 
    r = log(-log(r)); 
    r = c[0] + r*(c[1] + r*(c[2] + r*(c[3] + r*(c[4] + r*(c[5] + r*(c[6] + r*(c[7] + r*c[8]))))))); 
    if (x<0.0) r = -r; 
    return(r); 
} 

而且測試代碼

int m = 1000000, n = 1000; 
double z, p, dz = 1.0/double(m)/double(n); 
clock_t t1, t2; 
t1 = clock(); 
z = 1e-9; 
p = 0.0; 
for (int i = 0; i < m; i++) 
{ 
    for (int j = 0; j < n; j++) 
    { 
     z += dz * 0.999; 
     p = Inverse(z); 
    } 
} 
t2 = clock(); 
cout << z << '\t' << p << endl; 
cout << "Inverse" << '\t' << float(t2 - t1)/CLOCKS_PER_SEC << endl; 
+2

你正在做一個'if'。這意味着你要做更多的指示,這意味着更多的工作 – NathanOliver

+0

這兩個額外的納秒真的值得額外的努力嗎?這個差別最多隻是一個環境問題。 – Rakete1111

+3

這就是爲什麼必須快速執行的功能不應檢查其輸入,而是記錄預期範圍。讓用戶確保他們沒有違反該功能的要求。 –

回答

0

即使不執行異常,電腦照樣有檢查的變量「U」的價值在這種情況下,這需要時間。

相關問題