2009-02-02 2 views
4

У меня есть функция, которую я использую для добавления векторов, как это:Почему это невозможно оптимизировать?

public static Vector AddVector(Vector v1, Vector v2) 
{ 
    return new Vector(
     v1.X + v2.X, 
     v1.Y + v2.Y, 
     v1.Z + v2.Z); 
} 

Не очень интересно. Однако я перегружаю оператор «+» для векторов, а в перегрузке я вызываю функцию AddVector, чтобы избежать дублирования кода. Мне было любопытно, приведет ли это к двум вызовам метода или будет оптимизирована при компиляции или времени JIT. Я узнал, что это привело к двум вызовам метода, потому что мне удалось получить 10% в всего за счет дублирования кода AddVector, а также метода точечного продукта в методах перегрузки оператора «+» и «*». Конечно, это нишевой случай, потому что их называют десятками тысяч раз в секунду, но я этого не ожидал. Думаю, я ожидал, что метод будет встроен в другой или что-то еще. И я полагаю, что это не просто накладные расходы на вызов метода, но и копирование аргументов метода в другой метод (они являются структурами).

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

+0

http://www.codinghorror.com/blog/archives/001218.html – kd7

+0

микро-оптимизация? –

+0

99% времени, так как даже улучшение производительности на 10% в этом случае незначительно (встроенные вызовы метода VS 2). Какова была ваша абсолютная производительность? Я угадываю несколько MS в лучшем случае. См. Http://www.codinghorror.com/blog/archives/001218.html для примера. Не могу ответить на вопрос, хотя, извините. – James

ответ

1

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

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

  • Запуск под отладчиком будет отключить JIT оптимизации, что делает ваши измерения производительности недействительны.
  • Компиляция в режиме отладки также делает измерения производительности недействительными.
+0

Определенно верно. Изменение пользовательского типа вектора для класса в трассировщике лучей из codeproject.com (не может найти URL-адрес) привело к значительному повышению производительности. –

+0

Спасибо за полезную информацию :) Я только что изменил свои структуры на классы, и вот, значительный прирост производительности! Я тоже этого не ожидал, но я создам новый вопрос для вопросов, которые у меня есть. – JulianR

+0

Странно, я получил 10-кратное повышение производительности, когда переключился на структуры из классов. –

3

«И я полагаю, что это не просто накладные расходы на вызов метода, но также копирование аргументов метода в другой метод (они являются структурами)».

Почему бы вам не проверить это? Напишите версию AddVector, которая ссылается на две векторные структуры, а не на сами структуры.

+1

Это будет медленнее, чем передача по значению (в зависимости от размера структуры, но я говорю о рекомендуемом размере). –

5

Если вы скомпилируете в режим отладки или начинаете процесс с приложенного отладчика (хотя вы можете добавить его позже), то большого класса оптимизаций JIT, включая inlining, не произойдет.

Попробуйте перезапустить свои тесты, скомпилировав его в режиме деблокирования, а затем запустив его без отладки (Ctrl + F5 в VS) и посмотрите, видите ли вы оптимизированные ожидания.

0

Вы говорите, что Vector является структурой. Согласно a blog post from 2004, типы значений являются причиной неинтеграции метода. Я не знаю, изменились ли правила в это время.

+0

Типы значений могут быть встроены в x86 с .NET 3.5 SP1 (см. Http://blogs.msdn.com/vancem/archive/2008/05/12/what-s-coming-in-net-runtime-performance- в-версии-v3-5-sp1.aspx); x64 поддерживается inlining в более ранней версии, чем это, но я не уверен, какой именно ... –

1

У меня был VS в режиме Release, и я бежал без отладки, чтобы не винить. Запуск .exe в папке «Release» дает тот же результат. У меня установлен .NET 3.5 SP1.

И независимо от того, насколько я использую структуры, зависит от того, сколько я создаю что-то и насколько велико это при копировании по сравнению с ссылками.

0

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

+0

Поскольку это структура, GC не является проблемой. Единственное, что изменяется, это некоторые незначительные точки использования стека, но поскольку это возвращаемое значение, это даже незначительно. –

+0

О, я этого не понимал - Привет. – JSmyth