這常常會出現,因爲您的代碼在您引發事件時也必須進行空測試。抖動優化器無法做任何事情來優化無所事事的呼叫,它無法超越委託調用。這段代碼的快速版本,避免使委託調用:
public class Task {
public Action PostAction;
public void Do() {
if (PostAction != null) PostAction();
}
}
繪製與System.Diagnostics.Stopwatch的區別是非常棘手的,代表調用是相當快的。我確保Do()調用不能通過賦予[MethodImpl(MethodImplOptions.Noinlining)]屬性來內聯。我不是非常快的筆記本電腦平均測量與移動的Haswell芯片:
- 空DO():3.9納秒/調用
- 空測試:4.3納秒/呼叫= 4.3 - 3.9〜= 0.4納秒
- 調用:7.5納秒/呼叫= 7.5 - 3.9〜3.6 =納秒
當心的 「空DO()」 測量包括執行測試,一個用於(;;)環路的開銷以及使方法調用。這在所有測量中都是不變的開銷。
您可以告訴成本,委託調用比空測試(3.6 - 0.4)/ 0.4〜= 800%慢。如果你認爲不變的開銷是有代表性的(不是),你可以得到更友好的數字:(7.5 - 4.3)/ 4.3 - = 75%。你的foreach循環將會有更多的開銷,從而降低性能損失百分比。使用foreach迭代Enumerable.Range的測試(17.0 - 13.9)/ 13.9 - = 22%較慢。
這些當然是相當多的數字。但是,絕對值的數字非常低。如果你不經常打電話給委託人,或者有很多人(因此增加了不斷的開銷),那麼表演失敗就很難被注意到。
對於null的測試,正如演示如何引發事件的任何示例代碼所示,這是推薦的方法。如果您對代理將要被替換的期望很高(即事件將被訂閱),那麼您只有充分的理由使用lambda。在這種情況下,您優化了空檢查,每次調用節省大約一個CPU週期。
你可能比編寫這個問題的速度更快:-P – derape