C# функционируют нормальное возвращаемое значение VS или касательно аргумента

У меня есть метод в C#, который должен возвратить очень большой массив (или любая другая большая структура данных в этом отношении).

Существует ли увеличение производительности в использовании касательно или параметр вместо стандартного возвращаемого значения?

Т.Е. есть ли любая производительность или другое усиление в использовании

void function(sometype input, ref largearray)

largearray function(sometype input)
6
задан Jeff Atwood 16 May 2010 в 07:38
поделиться

4 ответа

Объем стека, используемый на 32-битном процессоре x86 для передачи аргументов различных типов:

  • байт: 4 байта
  • bool: 4 байта
  • enum: 4 байта
  • char: 4 байта
  • short: 4 байта
  • int: 4 байта
  • long: 8 байт
  • float: 4 байта
  • double: 8 байт
  • decimal: 16 байт
  • struct: размер структуры во время выполнения

  • string: 4 байта
  • массив: 4 байта
  • объект: 4 байта
  • интерфейс: 4 байта
  • указатель: 4 байта
  • экземпляр класса: 4 байта

Те, что ниже строки - ссылочные типы, их размер удвоится на 64-битном процессоре.

Для вызова статического метода первые 2 аргумента размером до 4 байт будут переданы через регистры процессора, а не через стек. Для вызова метода экземпляра только один аргумент будет передан через регистры. Остальные передаются в стек. 64-битный процессор поддерживает передачу 4 аргументов через регистры.

Как ясно из списка, единственный случай, когда вы должны рассматривать передачу аргумента по ссылке, это для структур. Обычное руководство для этого - делать это, когда структура больше 16 байт. Не всегда легко угадать размер структуры во время выполнения, обычно точным является размер до 4 полей. Меньше, если эти поля двойные, длинные или десятичные. В этом руководстве обычно рекомендуется превратить структуру в класс, именно по этой причине.

Также обратите внимание, что нет никакой экономии в передаче аргумента в виде байта или short намеренно, int - это тип, который устраивает 32-битный процессор. То же самое для доступных в настоящее время 64-битных процессоров.


Возвращаемое значение метода, настоящая тема вашего вопроса, почти всегда возвращается в регистре процессора. Большинство типов удобно размещаются в регистрах eax или edx:eax, регистр FPU для значений с плавающей точкой. Единственным исключением являются большие структуры и десятичные числа, они слишком велики, чтобы поместиться в регистре. Они вызываются путем резервирования места в стеке для возвращаемого значения и передачи 4-байтового указателя на это место в качестве аргумента метода.

5
ответ дан 16 December 2019 в 21:36
поделиться

Не будет никакой разницы между

void function(sometype input, out largearray output ) 

и

largearray function(sometype input)

Однако, если вы сделаете

largearray function( sometype input, ref largearray output )

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

1
ответ дан 16 December 2019 в 21:36
поделиться

Нет, просто верните массив

1
ответ дан 16 December 2019 в 21:36
поделиться

Параметр out возвращает ссылку на экземпляр типа, который не требовалось инициализировать перед отправкой в ​​метод.

Параметр ref возвращает ссылку на экземпляр типа, который должен быть инициализирован перед отправкой в ​​метод.

Речь идет о семантике вызовов, а НЕ о производительности.

1
ответ дан 16 December 2019 в 21:36
поделиться
Другие вопросы по тегам:

Похожие вопросы: