Определение локальной переменной const против класса const - PullRequest
47 голосов
/ 16 июня 2011

Если я использую константу, которая необходима только в методе , лучше ли объявлять const в области действия метода или в области действия класса?Есть ли лучшая производительность, объявляя это в методе?Если это так, я думаю, что более стандартным является определение их в области видимости (начало файла), чтобы изменить значение и упростить перекомпиляцию.

public class Bob
{
   private const int SomeConst = 100; // declare it here?
   public void MyMethod()
   {
      const int SomeConst = 100; // or declare it here?
      // Do soemthing with SomeConst
   }
}

Ответы [ 6 ]

47 голосов
/ 16 июня 2011

Нет повышения производительности при перемещении константы в класс. CLR достаточно умен, чтобы распознавать константы как константы, поэтому с точки зрения производительности они равны. Что действительно происходит при компиляции в IL, так это то, что значения констант жестко кодируются в программе компилятором как буквальные значения.

Другими словами, константа не является ссылочной ячейкой памяти. Это не переменная, это скорее литерал. Константа - это литерал, синхронизируемый в нескольких местах вашего кода. Так что это зависит от вас - хотя это более точное программирование, чтобы ограничить область действия константы тем, где она актуальна.

9 голосов
/ 16 июня 2011

Зависит от того, хотите ли вы использовать его на протяжении всего класса.Объявление верхнего уровня будет доступно во всем классе, а другое будет доступно только в MyMethod.Вы не получите никакого повышения производительности, если сделаете это в любом случае.

7 голосов
/ 16 июня 2011

Вот небольшой тест, который я сделал для оценки сценариев;

Код:

using System;
using System.Diagnostics;

namespace TestVariableScopePerformance
{
    class Program
    {
        static void Main(string[] args)
        {
            TestClass tc = new TestClass();
            Stopwatch sw = new Stopwatch();

            sw.Start();
            tc.MethodGlobal();
            sw.Stop();

            Console.WriteLine("Elapsed for MethodGlobal = {0} Minutes {1} Seconds {2} MilliSeconds", sw.Elapsed.Minutes, sw.Elapsed.Seconds, sw.Elapsed.Milliseconds);
            sw.Reset();

            sw.Start();
            tc.MethodLocal();
            sw.Stop();

            Console.WriteLine("Elapsed for MethodLocal = {0} Minutes {1} Seconds {2} MilliSeconds", sw.Elapsed.Minutes, sw.Elapsed.Seconds, sw.Elapsed.Milliseconds);

            Console.WriteLine("Press any key to continue...");
            Console.ReadKey();
        }


    }

    class TestClass
    {
        const int Const1 = 100;

        internal void MethodGlobal()
        {
            double temp = 0d;
            for (int i = 0; i < int.MaxValue; i++)
            {
                temp = (i * Const1);
            }
        }

        internal void MethodLocal()
        {
            const int Const2 = 100;
            double temp = 0d;
            for (int i = 0; i < int.MaxValue; i++)
            {
                temp = (i * Const2);
            }
        }
    }
}

Результаты 3 итераций:

Elapsed for MethodGlobal = 0 Minutes 1 Seconds 285 MilliSeconds
Elapsed for MethodLocal = 0 Minutes 1 Seconds 1 MilliSeconds
Press any key to continue...

Elapsed for MethodGlobal = 0 Minutes 1 Seconds 39 MilliSeconds
Elapsed for MethodLocal = 0 Minutes 1 Seconds 274 MilliSeconds
Press any key to continue...

Elapsed for MethodGlobal = 0 Minutes 1 Seconds 305 MilliSeconds
Elapsed for MethodLocal = 0 Minutes 1 Seconds 31 MilliSeconds
Press any key to continue...

Я думаю,наблюдение завершает @ jnm2 ответ.

Запустите тот же код из вашей системы и сообщите нам результат.

3 голосов
/ 16 июня 2011

Я стараюсь определять константы / переменные только в той минимальной области, в которой они мне нужны. В этом случае, если вы используете его только в пределах MyMethod, оставьте его там.

Это делает более понятным то, где применяется константа / переменная, а также избавляет вас от необходимости проверять (даже если это проверка компиляции), если константа упоминается в другом месте.

Исключением из этого может быть что-то «дорогое» (с точки зрения времени) для создания / вычисления, поэтому я мог бы захотеть, чтобы это определило экземпляр или статическое поле, поэтому мне придется вычислять его только один раз.

3 голосов
/ 16 июня 2011

Я бы поставил его в самом методе.Я не фанат переменных, которые находятся в области видимости, когда они не должны быть там.

1 голос
/ 16 июня 2011

Зависит от того, где вы хотите его использовать, если вы собираетесь использовать его в других методах, определите его в классе, если вы собираетесь использовать его только в одном методе, определите его в методе, который вы собираетесь использовать:)

...