簡體   English   中英

C#中算術溢出檢查的最佳實踐是什么?

[英]What are best practices for arithmetic overflow checking in C#?

關於'checked'關鍵字與編譯器選項'Check for arithmetic overflow / underflow'的使用,web / stackoverflow上有一些很好的文章,如下所示:

http://www.codethinked.com/c-trivia-what-no-overflow

為什么C#默認不使用算術溢出檢查?

在C#中處理整數溢出的最佳方法是什么?

我仍然不知道應該使用哪一個。 默認情況下,我更喜歡使用編譯器選項來保證安全,不要使用unchecked關鍵字混亂我的代碼,不要忘記它在某些地方,最后它不是很常用,所以許多開發人員可能都不知道。

但是,我采取的實際性能有多糟糕? 我想MS設置默認不進行溢出檢查是有充分理由的。 編譯器選項是僅涉及我的代碼還是每個使用的庫和框架本身?

我有同樣的問題。 我更喜歡在我公司的代碼中默認檢查一段代碼,因為溢出副作用可能會花費很多而且難以診斷。 發現這些副作用的真正原因可能是每一個有價值的。

問題是,我們在績效方面會失去什么?

這是一個非常簡單的工作台:

static void Main(string[] args)
{
    long c = 0;
    var sw = new Stopwatch();
    sw.Start();
    unchecked
    {
        for (long i = 0; i < 500000000; i++) c += 1;
    }
    sw.Stop();
    Console.WriteLine("Unchecked: " + sw.ElapsedMilliseconds);

    c = 0;
    sw.Restart();
    checked
    {
        for (long i = 0; i < 500000000; i++) c += 1;
    }
    sw.Stop();
    Console.WriteLine("Checked: " + sw.ElapsedMilliseconds);
}

在生成的IL中,我看到checkedunchecked關鍵字確定是否將使用add.ovfadd指令。 (適用於Debug和Release配置)

IL_001c:  ldloc.2
IL_001d:  ldc.i4.1
IL_001e:  conv.i8
IL_001f:  add


IL_0066:  ldloc.2
IL_0067:  ldc.i4.1
IL_0068:  conv.i8
IL_0069:  add.ovf

結果(x64主機)

調試

  • 未選中:2371
  • 檢查:2437

發布

  • 未選中:2088
  • 檢查:2266

通過int(s)替換long(s)的其他結果(x64主機)

調試

  • 未選中:1665
  • 檢查:1568

發布

  • 未選中:189
  • 檢查:566

性能受到影響,看起來選擇要檢查或取消選中的正確變量類型更為重要。 無論如何,它並沒有改變我的觀點。 我將在所有項目中打開“檢查算術溢出/下溢”! (高級構建設置)。

當需要性能時,我將簡單地使用未經檢查的塊。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM