2017-08-01 117 views
0

我目前正在進行指數衰減(http://www.acodersjourney.com/2016/02/26-handle-transient-errors-in-c/)實施。計算最大功率,使結果在極限內

我計算延遲等,使得:

var delay = (int) Math.Round(Math.Pow(timeBetweenAttempts, attempt), MidpointRounding.AwayFromZero); 

顯然,這種延遲開始變得非常大,非常快,甚至企圖爲10毫秒之間的時間。

我希望能夠做一些類似於:

var maxTimeBetweenAttempts = 5000; // 5 seconds is the hard limit 
var nominalTimeBetweenAttempts = 10; 

var maxNumberOfAttempts = // calculate the maximum number of raises that would hold below 5000. 

顯然,這可以用一個循環來計算的,但我不知道是否有一個更優雅的方式來做到這一點?

+1

爲什麼不只是使用'Math.Min(delay,maxTimeBetweenAttempts)'? –

+0

而不是'pow(x,n)',你需要一個延遲系列* pow(x/s,n)'。可以通過log(maxdelay/s)/ log(x/s)來確定最大的可接受的'n',這也是'(log(maxdelay)-log(s))/(log(x)-log(s ))'。事實上,你已經有了縮放因子,由你的首選單位隱式選擇。 10毫秒和0.01秒是相同的時間長度,但是如果你做了'pow(.01,n)',你會發現隨着'n'的增加,延遲變得更短*不再更長。 –

+0

@ScottChamberlain:因爲這並不能解決「延遲會很快變大」。 –

回答

0

指數的倒數是對數,所以你可以使用它。 你會使用

if (attempt < Math.Log(maxTimeBetweenAttempts)/Math.Log(nominalTimeBetweenAttempts)) 
{ 
    Retry(++attempt); 
} 

要查看嘗試是否低於閾值四捨五入後。

但是,由於這需要額外的計算,並且稍微不太明顯(因爲它使用的是對數數學,大多數人自從學校以來沒有發現過事件)而不僅僅是指數,我個人建議只計算功率和測試。

即。

if(Math.Pow(nominalTimeBetweenAttempts, attempt) < maxTimeBetweenAttempts) 
{ 
    Retry(++attempt); 
} 

編輯:

重讀你的問題,您明確指出你想知道的最大重試數達到一定長度之前。那將是:

var maximumNumberOfAttempts = Math.Floor(Math.Log(maxTimeBetweenAttempts)/Math.Log(nominalTimeBetweenAttempts)) 
+0

它看起來沒有回答你的問題。我錯過了什麼? – Max