Will using 'var' affect performance?

后端 未结 12 1494
南方客
南方客 2020-11-22 14:01

Earlier I asked a question about why I see so many examples use the varkeyword and got the answer that while it is only necessary for anonymous types, that it is used noneth

相关标签:
12条回答
  • 2020-11-22 14:22

    I always use the word var in web articles or guides writings.

    The width of the text editor of online article is small.

    If I write this:

    SomeCoolNameSpace.SomeCoolClassName.SomeCoolSubClassName coolClass = new SomeCoolNameSpace.SomeCoolClassName.SomeCoolSubClassName();
    

    You will see that above rendered pre code text is too long and flows out of the box, it gets hidden. The reader needs to scroll to the right to see the complete syntax.

    That's why I always use the keyword var in web article writings.

    var coolClass = new SomeCoolNameSpace.SomeCoolClassName.SomeCoolSubClassName();
    

    The whole rendered pre code just fit within the screen.

    In practice, for declaring object, I seldom use var, I rely on intellisense to declare object faster.

    Example:

    SomeCoolNamespace.SomeCoolObject coolObject = new SomeCoolNamespace.SomeCoolObject();
    

    But, for returning object from a method, I use var to write code faster.

    Example:

    var coolObject = GetCoolObject(param1, param2);
    
    0 讨论(0)
  • 2020-11-22 14:26

    I don't think you properly understood what you read. If it gets compiled to the correct type, then there is no difference. When I do this:

    var i = 42;
    

    The compiler knows it's an int, and generate code as if I had written

    int i = 42;
    

    As the post you linked to says, it gets compiled to the same type. It's not a runtime check or anything else requiring extra code. The compiler just figures out what the type must be, and uses that.

    0 讨论(0)
  • 2020-11-22 14:29

    As Joel says, the compiler works out at compile-time what type var should be, effectively it's just a trick the compiler performs to save keystrokes, so for example

    var s = "hi";
    

    gets replaced by

    string s = "hi";
    

    by the compiler before any IL is generated. The Generated IL will be exactly the same as if you'd typed string.

    0 讨论(0)
  • 2020-11-22 14:31

    If the compiler can do automatic type inferencing, then there wont be any issue with performance. Both of these will generate same code

    var    x = new ClassA();
    ClassA x = new ClassA();
    

    however, if you are constructing the type dynamically (LINQ ...) then var is your only question and there is other mechanism to compare to in order to say what is the penalty.

    0 讨论(0)
  • 2020-11-22 14:32

    It's depends of situation, if you try use, this code bellow.

    The expression is converted to "OBJECT" and decrease so much the performance, but it's a isolated problem.

    CODE:

    public class Fruta
    {
        dynamic _instance;
    
        public Fruta(dynamic obj)
        {
            _instance = obj;
        }
    
        public dynamic GetInstance()
        {
            return _instance;
        }
    }
    
    public class Manga
    {
        public int MyProperty { get; set; }
        public int MyProperty1 { get; set; }
        public int MyProperty2 { get; set; }
        public int MyProperty3 { get; set; }
    }
    
    public class Pera
    {
        public int MyProperty { get; set; }
        public int MyProperty1 { get; set; }
        public int MyProperty2 { get; set; }
    }
    
    public class Executa
    {
        public string Exec(int count, int value)
        {
            int x = 0;
            Random random = new Random();
            Stopwatch time = new Stopwatch();
            time.Start();
    
            while (x < count)
            {
                if (value == 0)
                {
                    var obj = new Pera();
                }
                else if (value == 1)
                {
                    Pera obj = new Pera();
                }
                else if (value == 2)
                {
                    var obj = new Banana();
                }
                else if (value == 3)
                {
                    var obj = (0 == random.Next(0, 1) ? new Fruta(new Manga()).GetInstance() : new Fruta(new Pera()).GetInstance());
                }
                else
                {
                    Banana obj = new Banana();
                }
    
                x++;
            }
    
            time.Stop();
            return time.Elapsed.ToString();
        }
    
        public void ExecManga()
        {
            var obj = new Fruta(new Manga()).GetInstance();
            Manga obj2 = obj;
        }
    
        public void ExecPera()
        {
            var obj = new Fruta(new Pera()).GetInstance();
            Pera obj2 = obj;
        }
    }
    

    Above results with ILSPY.

    public string Exec(int count, int value)
    {
        int x = 0;
        Random random = new Random();
        Stopwatch time = new Stopwatch();
        time.Start();
    
        for (; x < count; x++)
        {
            switch (value)
            {
                case 0:
                    {
                        Pera obj5 = new Pera();
                        break;
                    }
                case 1:
                    {
                        Pera obj4 = new Pera();
                        break;
                    }
                case 2:
                    {
                        Banana obj3 = default(Banana);
                        break;
                    }
                case 3:
                    {
                        object obj2 = (random.Next(0, 1) == 0) ? new Fruta(new Manga()).GetInstance() : new Fruta(new Pera()).GetInstance();
                        break;
                    }
                default:
                    {
                        Banana obj = default(Banana);
                        break;
                    }
            }
        }
    time.Stop();
    return time.Elapsed.ToString();
    }
    

    If you wish execute this code use the code bellow, and get the difference of times.

            static void Main(string[] args)
        {
            Executa exec = new Executa();            
            int x = 0;
            int times = 4;
            int count = 100000000;
            int[] intanceType = new int[4] { 0, 1, 2, 3 };
    
            while(x < times)
            {                
                Parallel.For(0, intanceType.Length, (i) => {
                    Console.WriteLine($"Tentativa:{x} Tipo de Instancia: {intanceType[i]} Tempo Execução: {exec.Exec(count, intanceType[i])}");
                });
                x++;
            }
    
            Console.ReadLine();
        }
    

    Regards

    0 讨论(0)
  • 2020-11-22 14:33

    There's no extra IL code for the var keyword: the resulting IL should be identical for non-anonymous types. If the compiler can't create that IL because it can't figure out what type you intended to use, you'll get a compiler error.

    The only trick is that var will infer an exact type where you may have chosen an Interface or parent type if you were to set the type manually.


    Update 8 Years Later

    I need to update this as my understanding has changed. I now believe it may be possible for var to affect performance in the situation where a method returns an interface, but you would have used an exact type. For example, if you have this method:

    IList<int> Foo()
    {
        return Enumerable.Range(0,10).ToList();
    }
    

    Consider these three lines of code to call the method:

    List<int> bar1 = Foo();
    IList<int> bar = Foo();
    var bar3 = Foo();
    

    All three compile and execute as expected. However, the first two lines are not exactly the same, and the third line will match the second, rather than the first. Because the signature of Foo() is to return an IList<int>, that is how the compiler will build the bar3 variable.

    From a performance standpoint, mostly you won't notice. However, there are situations where the performance of the third line may not be quite as fast as the performance of the first. As you continue to use the bar3 variable, the compiler may not be able to dispatch method calls the same way.

    Note that it's possible (likely even) the jitter will be able to erase this difference, but it's not guaranteed. Generally, you should still consider var to be a non-factor in terms of performance. It's certainly not at all like using a dynamic variable. But to say it never makes a difference at all may be overstating it.

    0 讨论(0)
提交回复
热议问题