У меня есть метод в C#, который должен возвратить очень большой массив (или любая другая большая структура данных в этом отношении).
Существует ли увеличение производительности в использовании касательно или параметр вместо стандартного возвращаемого значения?
Т.Е. есть ли любая производительность или другое усиление в использовании
void function(sometype input, ref largearray)
largearray function(sometype input)
Объем стека, используемый на 32-битном процессоре x86 для передачи аргументов различных типов:
Те, что ниже строки - ссылочные типы, их размер удвоится на 64-битном процессоре.
Для вызова статического метода первые 2 аргумента размером до 4 байт будут переданы через регистры процессора, а не через стек. Для вызова метода экземпляра только один аргумент будет передан через регистры. Остальные передаются в стек. 64-битный процессор поддерживает передачу 4 аргументов через регистры.
Как ясно из списка, единственный случай, когда вы должны рассматривать передачу аргумента по ссылке, это для структур. Обычное руководство для этого - делать это, когда структура больше 16 байт. Не всегда легко угадать размер структуры во время выполнения, обычно точным является размер до 4 полей. Меньше, если эти поля двойные, длинные или десятичные. В этом руководстве обычно рекомендуется превратить структуру в класс, именно по этой причине.
Также обратите внимание, что нет никакой экономии в передаче аргумента в виде байта или short намеренно, int - это тип, который устраивает 32-битный процессор. То же самое для доступных в настоящее время 64-битных процессоров.
Возвращаемое значение метода, настоящая тема вашего вопроса, почти всегда возвращается в регистре процессора. Большинство типов удобно размещаются в регистрах eax или edx:eax, регистр FPU для значений с плавающей точкой. Единственным исключением являются большие структуры и десятичные числа, они слишком велики, чтобы поместиться в регистре. Они вызываются путем резервирования места в стеке для возвращаемого значения и передачи 4-байтового указателя на это место в качестве аргумента метода.
Не будет никакой разницы между
void function(sometype input, out largearray output )
и
largearray function(sometype input)
Однако, если вы сделаете
largearray function( sometype input, ref largearray output )
и потребуете, чтобы вызывающая сторона предварительно выделила большой массив, это, конечно, будет быстрее, но это будет иметь значение, только если вы вызываете метод многократно и сохраняете большой массив выделенным между вызовами.
Параметр out
возвращает ссылку на экземпляр типа, который не требовалось инициализировать перед отправкой в метод.
Параметр ref
возвращает ссылку на экземпляр типа, который должен быть инициализирован перед отправкой в метод.
Речь идет о семантике вызовов, а НЕ о производительности.