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

Геттеры и сеттеры. Есть ли накладные расходы на производительность?

У меня есть механизм Particle System Engine в моем проекте на С++, и сами частицы - это просто структуры переменных без функций. В настоящее время каждая частица (Particle) обновляется из своего родительского класса (ParticleSystem) путем прямого доступа к своим переменным. Например.

particle.x += particle.vx;

Тем не менее, я обсуждаю использование геттеров и сеттеров следующим образом:

particle.setX( particle.getX()+particle.getVX() );

Мой вопрос: есть ли накладные расходы на производительность при вызове getters и seters, а не только прямому доступу к данным?

В конце концов, у меня есть много многих частиц для обновления через...

4b9b3361

Ответ 1

У сеттеров и геттеров есть служебные служебные данные , если они не оптимизированы. Они почти всегда оптимизированы для компиляторов, которые связывают оптимизацию времени. А на компиляторах, которые этого не делают, если у них есть знание о теле функции (то есть не только прототипе), оно будет оптимизировано.

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

Наконец, накладные расходы на работу геттера и сеттера в контексте оптимизированного кода очень малы, не стоит беспокоиться, если код не горячий. И если он горячий, это ТАК ЛЕГКО просто перемещать геттер или сеттер в файл заголовка и встраивать его.

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

Ответ 2

У меня другое мнение, чем предыдущие ответы.

Getters и seters являются признаками того, что ваш класс не разработан полезным образом: если вы не делаете внешнее поведение абстрактным из внутренней реализации, нет смысла использовать абстрактный интерфейс в первую очередь, вы можете а также использовать простую старую структуру.

Подумайте, какие операции вам действительно нужны. Это почти наверняка не прямой доступ к x-y- и z-координатам положения и импульса, вы скорее хотите рассматривать их как векторные величины (по крайней мере, в большинстве расчетов, что все, что имеет значение для оптимизация). Таким образом, вы хотите реализовать векторный интерфейс *, где основными операциями являются векторное сложение, масштабирование и внутренний продукт. Не компонентный доступ; вам, вероятно, также нужно делать это иногда, но это можно сделать с помощью одного члена std::array<double,3> to_posarray() или что-то в этом роде.

Когда внутренние компоненты x, y... vz недоступны извне, вы можете безопасно изменить внутреннюю реализацию, не торгуя никаким кодом вне вашего модуля. Это в значительной степени все зависит от геттеров/сеттеров; однако при использовании этих возможностей существует только такая оптимизация, которую вы можете сделать: любое реальное изменение реализации с неизбежностью делает геттеры намного медленнее. С другой стороны, вы можете оптимизировать ад из векторного интерфейса, с SIMD-операциями, внешними вызовами библиотеки (возможно, на ускоренном оборудовании, например CUDA) и т.п. "Batch-getter", например, to_posarray, все еще может быть реализован достаточно эффективно, установки с одной переменной не могут.


* Я имею в виду вектор в математический смысл, а не как std::vector.

Ответ 3

Getters и seters позволяют вашему коду развиваться более легко в будущем, если получение и настройка оказываются несколько более сложными задачами. Большинство компиляторов С++ достаточно интеллектуальны для inline этих простых методов и устраняют накладные расходы на вызов функции.

Ответ 4

На этот вопрос могут быть ответы на разные вопросы, но я тут же придумываю свои мысли.

Для производительности стоимость может быть в основном проигнорирована для простого типа POD. Но все равно стоит, и это зависит от того, какой тип вы вернетесь. Для частиц не могло быть много данных. Если это класс изображения (например, OpenCV cv:: Mat) или 3d-данные (например, PolyData в VTK), лучше, чтобы setter/getter работал с указателями/итераторами, чем с фактическими данными, чтобы избежать проблемы с распределением памяти.

Если вы хотите создавать шаблоны, то сеттер/получатель может быть полезным, чтобы избежать неявного преобразования типов. Сеттер/получатель может быть способом доступа к частному/защищенному элементу, что также позволяет избежать использования x в качестве общего имени переменной. Более того, setter/getter может возвращать ссылку Lvalue, которая позволяет вам делать particle.getX() = 10.0 ;