Существуют ли дополнительные затраты времени выполнения для использования именованных параметров? - PullRequest
2 голосов
/ 21 мая 2010

Рассмотрим следующую структуру:

    public struct vip
    {
        string email;
        string name;
        int category;

        public vip(string email, int category, string name = "")
        {
            this.email = email;
            this.name = name;
            this.category = category;
        }
    }

Есть ли разница в производительности между следующими двумя вызовами?

var e = new vip(email: "foo", name: "bar", category: 32);

var e = new vip("foo", 32, "bar");

Есть ли разница, если не определены необязательные параметры?

Ответы [ 5 ]

5 голосов
/ 21 мая 2010

Я не верю никому. Это только функция языка / компилятора, если хотите, назовите ее синтаксическим сахаром Сгенерированный код CLR должен быть таким же.

3 голосов
/ 21 мая 2010

Существует стоимость времени компиляции, но не времени выполнения ... и время компиляции составляет очень , очень минута.

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

Подумайте об этом так: если вы используете все параметры, компилятор вызовет метод, используя все из них, в противном случае он создаст что-то вроде этого за кулисами:

 var e = new vip(email: "foo", category: 32); //calling

 //generated, this is what it's actually saving you from writing
 public vip(string email, int category) : this(email, category, "bar") { }
1 голос
/ 28 апреля 2013

На самом деле, стоит x64 CLR

Посмотрите здесь http://www.dotnetperls.com/named-parameters

Я могу воспроизвести результат: именованный вызов занимает 4,43 нс, а обычный вызов занимает 3,48 нс (программа работает в x64)

Однако в x86 оба требуют около 0,32 нс

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

Примечаниечто в VS2012 по умолчанию targat является AnyCPU x86, вы должны переключиться на x64, чтобы увидеть разницу.

using System;
using System.Diagnostics;

class Program
{
    const int _max = 100000000;
    static void Main()
    {
    Method1();
    Method2();

    var s1 = Stopwatch.StartNew();
    for (int i = 0; i < _max; i++)
    {
        Method1();
    }
    s1.Stop();
    var s2 = Stopwatch.StartNew();
    for (int i = 0; i < _max; i++)
    {
        Method2();
    }
    s2.Stop();
    Console.WriteLine(((double)(s1.Elapsed.TotalMilliseconds * 1000 * 1000) /
        _max).ToString("0.00 ns"));
    Console.WriteLine(((double)(s2.Elapsed.TotalMilliseconds * 1000 * 1000) /
        _max).ToString("0.00 ns"));
    Console.Read();
    }

    static void Method1()
    {
    Method3(flag: true, size: 1, name: "Perl");
    }

    static void Method2()
    {
    Method3(1, "Perl", true);
    }

    static void Method3(int size, string name, bool flag)
    {
    if (!flag && size != -1 && name != null)
    {
        throw new Exception();
    }
    }
}
1 голос
/ 21 мая 2010

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

В отношении именованных параметров следует помнить, что имена теперь являются частью сигнатуры для вызова метода (если он используется явно) во время компиляции. То есть если имена меняются, код вызова также должен быть изменен, если вы перекомпилируете. Развернутая сборка, с другой стороны, не будет затронута до перекомпиляции, так как имена не присутствуют в IL.

1 голос
/ 21 мая 2010

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

РЕДАКТИРОВАТЬ: обратите внимание, что, поскольку они являются функцией компилятора, это означает, что изменения в параметрах обновляются только при перекомпиляции «клиентов». Так, например, если вы измените значение по умолчанию для необязательного параметра, вам нужно будет перекомпилировать все «клиенты», иначе они будут использовать старое значение по умолчанию.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...