Повлияет ли использование var на производительность? - PullRequest
217 голосов
/ 10 декабря 2008

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

После по этой ссылке ("C # 3.0 - Var Is Not Objec") Я видел, что var компилируется до нужного типа в IL (вы увидите это в середине статьи) .

У меня вопрос, насколько больше, если таковой имеется, IL-кода использует ключевое слово var, и будет ли оно даже близко к измеряемому уровню производительности кода, если бы он использовался повсеместно?

Ответы [ 12 ]

299 голосов
/ 10 декабря 2008

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

Единственная хитрость в том, что var выведет точный тип, если вы, возможно, выбрали интерфейс или родительский тип, если бы вам пришлось установить тип вручную.


Обновление 8 лет спустя

Мне нужно обновить это, так как мое понимание изменилось. Теперь я верю, что var может повлиять на производительность в ситуации, когда метод возвращает интерфейс, но вы бы использовали точный тип. Например, если у вас есть этот метод:

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

Рассмотрим эти три строки кода для вызова метода:

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

Все три компилируются и выполняются, как и ожидалось. Однако первые две строки не абсолютно одинаковы, а третья строка будет соответствовать второй, а не первой. Поскольку подпись Foo() должна возвращать IList<int>, именно так компилятор будет создавать переменную bar3.

С точки зрения производительности, в большинстве случаев вы этого не заметите. Однако существуют ситуации, когда производительность третьей строки может быть не такой быстрой, как производительность первой . Поскольку вы продолжаете использовать переменную bar3, компилятор может не иметь возможности отправлять вызовы методов одинаково.

Обратите внимание, что возможно (вероятно, даже) дрожание сможет стереть эту разницу, но это не гарантируется. Как правило, вы все равно должны рассматривать var как фактор, не влияющий на производительность. Это совсем не то же самое, что использование переменной dynamic. Но сказать, что это никогда не имеет значения, может быть преувеличивать.

70 голосов
/ 10 декабря 2008

Как говорит Джоэл, компилятор работает на время компиляции , каким должен быть тип var, фактически это всего лишь прием, который компилятор выполняет для сохранения нажатий клавиш, например

var s = "hi";

заменяется на

string s = "hi";

компилятором до генерации любого IL. Сгенерированный IL будет точно таким же, как если бы вы набрали строку.

25 голосов
/ 18 ноября 2009

Как никто еще не упомянул отражатель ...

Если вы компилируете следующий код C #:

static void Main(string[] args)
{
    var x = "hello";
    string y = "hello again!";
    Console.WriteLine(x);
    Console.WriteLine(y);
}

Тогда используйте отражатель, вы получите:

// Methods
private static void Main(string[] args)
{
    string x = "hello";
    string y = "hello again!";
    Console.WriteLine(x);
    Console.WriteLine(y);
}

Таким образом, ответ явно не влияет на производительность во время выполнения!

17 голосов
/ 22 февраля 2011

Для следующего метода:

   private static void StringVsVarILOutput()
    {
        var string1 = new String(new char[9]);

        string string2 = new String(new char[9]);
    }

Выход IL:

        {
          .method private hidebysig static void  StringVsVarILOutput() cil managed
          // Code size       28 (0x1c)
          .maxstack  2
          .locals init ([0] string string1,
                   [1] string string2)
          IL_0000:  nop
          IL_0001:  ldc.i4.s   9
          IL_0003:  newarr     [mscorlib]System.Char
          IL_0008:  newobj     instance void [mscorlib]System.String::.ctor(char[])
          IL_000d:  stloc.0
          IL_000e:  ldc.i4.s   9
          IL_0010:  newarr     [mscorlib]System.Char
          IL_0015:  newobj     instance void [mscorlib]System.String::.ctor(char[])
          IL_001a:  stloc.1
          IL_001b:  ret
        } // end of method Program::StringVsVarILOutput
15 голосов
/ 20 августа 2015

Итак, чтобы быть ясным, это ленивый стиль кодирования. Я предпочитаю нативные типы, учитывая выбор; Я возьму этот лишний «шум», чтобы убедиться, что я пишу и читаю именно то, что, как мне кажется, находится во время кода / отладки. * пожав плечами *

13 голосов
/ 10 декабря 2008

Компилятор C # определяет истинный тип переменной var во время компиляции. Там нет разницы в сгенерированном IL.

8 голосов
/ 10 декабря 2008

Не думаю, что вы правильно поняли, что читаете. Если он скомпилирован в правильный тип, тогда - это без разницы. Когда я делаю это:

var i = 42;

Компилятор знает , что это int, и генерирует код, как если бы я написал

int i = 42;

Как говорится в сообщении, на которое вы ссылаетесь, оно скомпилируется того же типа. Это не проверка во время выполнения или что-то еще, требующее дополнительного кода. Компилятор просто выясняет, каким должен быть тип, и использует его.

5 голосов
/ 10 декабря 2008

Нет никаких затрат производительности при использовании var. Хотя я подозреваю, что производительность компиляции будет снижена, поскольку компилятор должен определить тип, хотя это, скорее всего, будет незначительным.

3 голосов
/ 21 июля 2014

Я всегда использую слово var в веб-статьях или руководствах.

Ширина текстового редактора онлайн-статьи мала.

Если я напишу это:

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

Вы увидите, что приведенный выше текст предварительного кода слишком длинный и вытекает из поля, он скрыт. Читатель должен прокрутить вправо, чтобы увидеть полный синтаксис.

Вот почему я всегда использую ключевое слово var в записях веб-статей.

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

Весь обработанный предварительный код просто помещается на экране.

На практике для объявления объекта я редко использую var, я полагаюсь на intellisense для более быстрого объявления объекта.

Пример:

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

Но для возврата объекта из метода я использую var, чтобы быстрее писать код.

* * Пример тысяча двадцать-один: * * 1 022
var coolObject = GetCoolObject(param1, param2);
3 голосов
/ 10 декабря 2008

Если компилятор может делать автоматическое определение типа, то с производительностью проблем не будет. Оба они будут генерировать один и тот же код

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

однако, если вы создаете тип динамически (LINQ ...), тогда var - ваш единственный вопрос, и есть другой механизм для сравнения, чтобы сказать, каков штраф.

...