Подтвердить что ты не робот

Стоимость использования параметров в С#

Есть ли у кого-нибудь советы по использованию параметров в С# для передачи аргументов метода. Я рассматриваю возможность перегрузки для первых 6 аргументов, а затем 7-го, используя функцию params. Мое рассуждение состоит в том, чтобы избежать дополнительного распределения массива, требуемого параметрами. Это для некоторых высокопроизводительных методов полезности. Любой совет? Это пустая трата кода для создания всех перегрузок?

4b9b3361

Ответ 1

Честно говоря, меня немного беспокоят все, кто кричит "преждевременная оптимизация!". Вот почему.

  • То, что вы говорите, имеет смысл, особенно если вы уже указали, что работаете над высокопроизводительной библиотекой.
  • Даже классы BCL следуют этому шаблону. Рассмотрим все перегрузки string.Format или Console.WriteLine.
  • Это очень легко получить право. Вся предпосылка движения против преждевременной оптимизации заключается в том, что когда вы делаете что-то сложное в целях оптимизации производительности, вы можете случайно сломать что-то и сделать код менее ремонтопригодным. Я не понимаю, как эта опасность здесь; это должно быть очень просто, что вы делаете, для себя, а также для любого будущего разработчика, который может иметь дело с вашим кодом.

Кроме того, даже если вы профилировали результаты обоих подходов и видели только очень небольшую разницу в скорости, все равно проблема выделения памяти. Создание нового массива для каждого вызова метода влечет за собой выделение большего объема памяти, которое нужно будет собирать позже. И в некоторых сценариях, где желательно "почти" поведение в режиме реального времени (например, алгоритмическая торговля, поле, в котором я работаю), минимизация сборок мусора столь же важна, как и максимальная скорость выполнения.

Итак, даже если он заработает мне несколько downvotes: я говорю, пойдите для этого.

(И тем, кто утверждает, что "компилятор, безусловно, уже делает что-то подобное", - я бы не был так уверен. Во-первых, если это так, я не понимаю, почему классы BCL будут следовать этому шаблону, поскольку Я уже упоминал, но что более важно, существует очень большая семантическая разница между методом, который принимает несколько аргументов, и тот, который принимает массив. Просто потому, что можно использовать в качестве замены для другого, это не значит, что компилятор, или должен, попытаться такую ​​замену).

Ответ 2

Да, эта стратегия, используемая платформой .NET. String.Concat() будет хорошим примером. Он имеет перегрузки для четырех строк, плюс резервный, который берет строку params []. Здесь очень важно, что Concat должен быть быстрым и помочь пользователю попасть в успех, когда он использует оператор + вместо StringBuilder.

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

Fwiw: в среде .NET есть много таких микро-оптимизаций. В некоторой степени необходимо, потому что дизайнеры не могли предсказать, как их классы будут использоваться. String.Concat() так же вероятен в жестком внутреннем цикле, который имеет решающее значение для программной функции, как, скажем, для конфигурационного считывателя, который запускается только один раз при запуске. Как конечный пользователь вашего собственного кода, вам, как правило, не нужно беспокоиться об этом. Верно и обратное: рамочный код .NET чрезвычайно свободен от микрооптимизации, когда маловероятно, что их польза будет измерима. Как и предоставление перегрузок, когда основной код в любом случае медленный.

Ответ 3

Вы всегда можете передать Tuple в качестве параметра или если типы параметров всегда одинаковы, IList<T>.

Как и другие ответы и комментарии, вы должны оптимизировать только после:

  • Обеспечение правильного поведения.
  • Определение необходимости оптимизации.

Ответ 4

Моя точка зрения: если ваш метод способен получать неограниченное количество параметров, то логика внутри него работает в стиле массива. Таким образом, перегрузка для ограниченного числа параметров не помогла бы. Если вы не можете реализовать ограниченное количество параметров по-разному, это намного быстрее.

Например, если вы передаете параметры Console.WriteLine, там есть и скрытое создание массива, поэтому в любом случае вы получаете массив.

И, извините за беспокойство Дэна Тао, я также чувствую, что это преждевременная оптимизация. Потому что вам нужно знать, какая разница, чтобы иметь перегрузки с ограниченным числом параметров. Если ваше приложение критично критично, вам нужно реализовать оба способа и попытаться запустить тест и сравнить время выполнения.

Ответ 5

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

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

Ответ 6

Вы можете попробовать что-то вроде this, чтобы сравнить производительность, чтобы у вас были конкретные номера для принятия решений.

В общем случае выделение объектов немного быстрее, чем в C/С++, и удаление значительно, намного быстрее для небольших объектов - пока у вас не будет десятки тысяч из них в секунду. Здесь приведена старая статья о производительности распределения памяти.