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

前端 未结 7 660
庸人自扰
庸人自扰 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条回答
  •  Happy的楠姐
    2020-12-14 00:07

    Apparently in real life it isn't faster. Check this: https://dotnetfiddle.net/lZKHmn

    Turns out, that thanks to Intel's branch prediction and parallel execution the more obvious and readable code actually works faster...

    Here's the code:

    using System;
    using System.Diagnostics;
    
    public class Program
    {
    
    
        const int MAX_ITERATIONS = 10000000;
        const int MAX_SIZE = 1000;
    
    
        public static void Main()
        {
    
                var timer = new Stopwatch();
    
    
                Random rand = new Random();
                long InRange = 0;
                long OutOfRange = 0;
    
                timer.Start();
                for ( int i = 0; i < MAX_ITERATIONS; i++ ) {
                    var x = rand.Next( MAX_SIZE * 2 ) - MAX_SIZE;
                    if ( x < 0 || x > MAX_SIZE ) {
                        OutOfRange++;
                    } else {
                        InRange++;
                    }
                }
                timer.Stop();
    
                Console.WriteLine( "Comparision 1: " + InRange + "/" + OutOfRange + ", elapsed: " + timer.ElapsedMilliseconds + "ms" );
    
    
                rand = new Random();
                InRange = 0;
                OutOfRange = 0;
    
                timer.Reset();
                timer.Start();
                for ( int i = 0; i < MAX_ITERATIONS; i++ ) {
                    var x = rand.Next( MAX_SIZE * 2 ) - MAX_SIZE;
                    if ( (uint) x > (uint) MAX_SIZE ) {
                        OutOfRange++;
                    } else {
                        InRange++;
                    }
                }
                timer.Stop();
    
                Console.WriteLine( "Comparision 2: " + InRange + "/" + OutOfRange + ", elapsed: " + timer.ElapsedMilliseconds + "ms" );
    
        }
    }
    

提交回复
热议问题