Приводит ли передача типа значения в выходной параметр к упаковке переменной?

Я знаю, что упаковка и распаковка относительно дороги с точки зрения производительности. . Что мне интересно:

Приводит ли передача типа значения к параметру метода out к упаковке / распаковке переменной (и, следовательно, к снижению производительности)? Может ли компилятор это оптимизировать?

  int number;
  bool result = Int32.TryParse(value, out number);

person Justin Morgan    schedule 26.01.2011    source источник
comment
Предварительная оптимизация поиска. Разбор целого числа (разбор в целом) намного дороже, чем простая операция упаковки.   -  person Dykam    schedule 26.01.2011
comment
@Dykam: Верно. Я просто использую TryParse в качестве примера.   -  person Justin Morgan    schedule 26.01.2011


Ответы (4)


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

Упаковка происходит только тогда, когда значение типа значения преобразуется в значение ссылочного типа, и в вашем примере нет никакого преобразования. Типом ссылки, конечно же, должен быть System.Object, System.ValueType, System.Enum или любой интерфейс. Обычно это довольно ясно; в коде есть явное или неявное преобразование. Однако могут быть обстоятельства, когда это менее ясно. Например, когда вызывается непереопределенный виртуальный метод базового типа структуры, происходит упаковка. (Существуют также причудливые ситуации, в которых определенные виды ограничений универсального типа могут вызывать неожиданную упаковку, но на практике они обычно не возникают.)

person Eric Lippert    schedule 26.01.2011
comment
Спасибо за ответ. Есть ли еще проблема с производительностью? Как это соотносится с попаданиями из упаковки / распаковки, передачи ссылочного типа или передачи типа значения? - person Justin Morgan; 26.01.2011
comment
@Justin: Лучший совет по любому вопросу о производительности: попробуйте, и вы узнаете. Вы, вероятно, обнаружите, что обычно передача переменной по ссылке является той же стоимостью, что и передача ссылки на экземпляр ссылочного типа по ссылке, что является той же стоимостью, что и передача типа значения размера IntPtr. Имейте в виду, что передачу параметров размером с указатель можно сильно оптимизировать из-за джиттера, если есть доступные регистры. - person Eric Lippert; 27.01.2011

Без упаковки, компилятор использует инструкцию ldloca.s, которая помещает ссылку на локальную переменную в стек (http://msdn.microsoft.com/en-us/library/system.reflection.emit.opcodes.ldloca_s(VS. 71) .aspx)

.method private hidebysig static void Func() cil managed
{
    .maxstack 2
    .locals init (
        [0] int32 num,
        [1] bool flag)
    L_0000: nop 
    L_0001: ldstr "5"
    L_0006: ldloca.s num
    L_0008: call bool [mscorlib]System.Int32::TryParse(string, int32&)
    L_000d: stloc.1 
    L_000e: ret 
}
person alexdej    schedule 26.01.2011

Нет, бокса (обязательного / задействованного) нет.

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

Компилятор «каким-то образом» создает ссылку на исходную переменную.

person Henk Holterman    schedule 26.01.2011
comment
Спасибо за ответ. Вы знаете, есть ли еще проблема с производительностью? Как это соотносится с попаданием из бокса / распаковки или с передачей обычных параметров? - person Justin Morgan; 26.01.2011
comment
@Justin накладные расходы будут зависеть от обстоятельств (поле или локальная переменная), но для локального out, вероятно, будет самым быстрым. Вам нужно будет оценить вашу ситуацию. Но в лучшем случае это микрооптимизация, и реальных альтернатив нет. - person Henk Holterman; 26.01.2011

Бокса нет; параметр out указывает, что номер должен быть назначен в методе TryParse. Независимо от этого, он по-прежнему рассматривается как int, а не object.

person Mark Avenius    schedule 26.01.2011