Свойства медленнее чем поля - PullRequest
0 голосов
/ 14 декабря 2018

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

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

Профилирование кода в режиме выпуска с включенной оптимизацией привело к многочисленным вызовам функций get свойства.Вызовы Copy() составляют до ~ 5,6 мс.

Properties benchmark

Однако, когда свойства преобразуются в поля, функция выполняется в 6 раз быстрее, чемэто было сделано со свойствами:

enter image description here

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

enter image description here

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

РЕДАКТИРОВАТЬ: Кажется, что некоторые (но не во всех) случаи, затронутые этой проблемой, используют свойства, объявленные в интерфейсах.Никакой другой полиморфизм не используется в этих случаях, но удаление интерфейса приводит к изменению производительности в ожидаемых уровнях в этих случаях.

РЕДАКТИРОВАТЬ 2: Как указано в предыдущем редактировании, кажется, чтоЧастично проблема была связана с интерфейсом виртуальных вызовов.После дополнительных исследований кажется, что выполнение эталонного теста в CLR правильно указывает свойства, но JetBrains dotTrace этого не делает, даже если установлен флажок «Включить встроенный».

1 Ответ

0 голосов
/ 14 декабря 2018

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

[MethodImpl(MethodImplOptions.AggressiveInlining)]

AggressiveInlining Метод должен быть встроен, если это возможно.

Теперь технически это можно использовать только для метода или конструктора, однако вы можете проверить его на геттере и установить сами.то есть он компилируется (хотя я не проверял это)

public int someType
{
   [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
   get;
   [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
   set;
}

Примечание : вставка - это черный ящик с удивлением, дрожание может ощущаться как это или нет,даже атрибут является только предложением.Также обратите внимание, что битность может также влиять на то, что она встроена.

Наконец, я думаю, что вы идете по этому пути правильно, вы должны просто использовать bechmarker или профилировщик, и микро оптимизировать соответственно,

...