Is it more efficient to perform a range check by casting to uint instead of checking for negative values?

前端 未结 7 667
庸人自扰
庸人自扰 2020-12-13 23:31

I stumbled upon this piece of code in .NET\'s List source code:

// Following trick can reduce the range check by one
if ((uint) index >= (uint)_size) {
           


        
7条回答
  •  甜味超标
    2020-12-14 00:07

    Assuming _sizeis an integer, private to the list and index is the argument to this function which's validity needs to be tested.

    Assuming further that _size is always >= 0.

    Then the original test would have been:

    if(index < 0 || index > size) throw exception
    

    The optimized version

    if((uint)index > (uint)_size) throw exception
    

    has one comparison (as opsed to two int he former example.) Because the cast just reinterpretes the bits and makes the >in fact an unsigned comparison, no additonal CPU cycles are used for it.

    Why does it work?

    The results are simple/trivial as long as index >= 0.

    If index < 0 the (uint)index will turn it into a very large number:

    Example: 0xFFFF is -1 as int, but 65535 as uint, thus

    (uint)-1 > (uint)x 
    

    is always true if x was positive.

提交回复
热议问题