передача по ссылке in
кажется логически эквивалентной передаче по значению.
Правильно.
Есть ли какое-то преимущество в производительности?
Да.
Я считал, что на стороне сервера, параметр ref
должен по крайней мере копировать физический адрес переменной,который должен быть того же размера, что и любая типичная ссылка на объект.
Не существует требования о том, чтобы ссылка на объект и ссылка на переменную имели одинаковый размер,и не существует требования , которое либо является размером машинного слова, но да, на практике оба являются 32-битными на 32-битных машинах и 64-битными на 64-битных машинах.
Что вы думаете о «физическом адресе», мне неясно. В Windows мы используем виртуальных адресов , а не физических адресов в коде режима пользователя.При каких возможных обстоятельствах вы представляете, что физический адрес имеет значение в программе на C #, мне любопытно знать.
Нет также требования о том, что ссылка любого вида должна быть реализована.как виртуальный адрес хранилища.Ссылки могут быть непрозрачными дескрипторами в таблицы GC в соответствующей реализации спецификации CLI.
- это преимущество только в больших структурах?
Снижение стоимости прохождения больших структур мотивирующий сценарий для функции.
Обратите внимание, что нет гарантии, что in
сделает любую программу на самом деле быстрее, а может замедлить работу программ. На все вопросы об эффективности необходимо ответить эмпирическим исследованием .Существует очень мало оптимизаций, которые всегда выигрывают ;Это не оптимизация «всегда выигрывать».
Есть ли какая-то закулисная оптимизация компилятора, которая делает его привлекательным в других местах?
Компилятору и среде выполнения разрешено выполнять любую оптимизацию, которую они выбирают, если это не нарушает правила спецификации C #.Насколько мне известно, такая оптимизация для in
параметров еще не реализована, но это не исключает возможности такой оптимизации в будущем.
почему я не должен делать каждый параметр входным?
Итак, предположим, что вы указали параметр int
вместо параметра in int
.Какие расходы налагаются?
- на сайте вызова теперь требуется переменная , а не значение
- переменная не может быть зарегистрирована.Тщательно настроенная схема распределения регистров джиттера только что добавила в него гаечный ключ.
- код на сайте вызовов больше, потому что он должен взять ссылку на переменную и поместить ее в стек, тогда как прежде чем он могпросто поместите значение в стек вызовов
- кода большего размера, что означает, что некоторые инструкции по быстрому переходу теперь могут стать инструкциями по длинному переходу, поэтому снова код становится больше.Это влияет на все виды вещей.Кеши заполняются быстрее, у джиттера есть больше работы, джиттер может решить не выполнять определенную оптимизацию при больших размерах кода и т. Д.
- на сайте вызываемого абонента, мы открыли доступ кзначение в стеке (или регистр) в косвенном направлении в указатель.Теперь этот указатель, скорее всего, будет находиться в кеше, но мы все же превратили доступ к значению из одной инструкции в доступ из двух инструкций.
- И так далее.
Предположим, что это double
, а вы измените его на in double
.Опять же, теперь переменная не может быть зарегистрирована в высокопроизводительном регистре с плавающей запятой.Это не только влияет на производительность , но также может изменить поведение программы!C # разрешается выполнять арифметику с плавающей точкой с точностью выше 64 бит и обычно делает это только в том случае, если числа с плавающей точкой могут быть зарегистрированы.
Это не бесплатная оптимизация.Вы должны измерить его эффективность против альтернатив.Лучше всего в первую очередь просто не создавать большие структуры, как предлагают рекомендации по проектированию.