Влияют ли геттеры и сеттеры на производительность в C ++ / D / Java?

В течение года вы должны использовать нижний регистр y:

final DateTimeFormatter DATE_FORMAT = DateTimeFormatter.ofPattern("dd-MM-yyyy");

Верхний регистр Y используется для недельного периода. Подробнее см. javadoc of DateTimeFormatter .

30
задан vaxquis 24 November 2015 в 14:46
поделиться

9 ответов

Это зависит от обстоятельств. Не существует универсального ответа, который всегда был бы правдой.

В Java JIT-компилятор, вероятно, встроит его рано или поздно . Насколько мне известно, JIT-компилятор JVM оптимизирует только часто используемый код, поэтому вы можете видеть накладные расходы на вызов функции изначально, пока геттер / сеттер не будет вызываться достаточно часто.

В C ++ он почти наверняка будет встроен ( при условии, что оптимизация включена). Однако есть один случай, когда этого, вероятно, не будет:

// foo.h
class Foo {
private:
  int bar_;

public:
  int bar(); // getter
};

// foo.cpp
#include "foo.h"

int Foo::bar(){
  return bar_;
}

Если определение функции не видно пользователям класса (который будет включать foo.h, но выиграл) t см. foo.cpp), то компилятор может не иметь возможности встроить вызов функции.

MSVC должен иметь возможность встроить его, если генерация кода во время компоновки включена в качестве оптимизации. Я не знаю, как GCC решает эту проблему.

В расширении это также означает, что если получатель определен в другой .dll / .so, вызов не может быть встроен.

] В любом случае, я не думаю, что тривиальные методы получения / установки обязательно являются «хорошей практикой ООП» или что существуют «все другие причины для их использования». Многие люди считают тривиальные методы получения / установки 1) признаком плохого дизайна и 2) пустой тратой набора текста.

Лично я в любом случае не волнуюсь по этому поводу. Для меня, чтобы что-то квалифицировалось как «хорошая практика ООП», оно должно иметь поддающиеся количественной оценке положительные эффекты. Тривиальные методы получения / установки имеют некоторые незначительные преимущества, а некоторые - столь же незначительные недостатки. Поэтому я не думаю, что это хорошая или плохая практика. Это просто то, что вы можете сделать, если действительно захотите.

24
ответ дан 27 November 2019 в 22:07
поделиться

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


Изменить: Например, строки:

S s;
s.foo = s.bar + 1;

будет работать как для

struct S
{
     int foo;
     int bar;
}

, так и для

struct S
{
     void foo(int) { ... }
     int bar() { ... return something; }
}
9
ответ дан 27 November 2019 в 22:07
поделиться

I однажды был точно такой же вопрос.

Чтобы ответить на этот вопрос, я запрограммировал две небольшие программы:

Первая:

#include <iostream>

class Test
{
     int a;
};

int main()
{
    Test var;

    var.a = 4;
    std::cout << var.a << std::endl;
    return 0;
}

Вторая:

#include <iostream>

class Test
{
     int a;
     int getA() { return a; }
     void setA(int a_) { a=a_; }
};

int main()
{
    Test var;

    var.setA(4);
    std::cout << var.getA() << std::endl;
    return 0;
}

Я скомпилировал их на ассемблер с -O3 (полностью оптимизирован) и сравнил два файла. Они были идентичны. Без оптимизации они были другими.

Это было под g ++. Итак, отвечая на ваш вопрос: компиляторы легко оптимизируют геттеры и сеттеры.

6
ответ дан 27 November 2019 в 22:07
поделиться

В некоторых случаях для некоторых членов потребуется геттер. Однако предоставление геттера и сеттера для каждого члена данных класса не является хорошей практикой. Это усложнило бы интерфейс класса. Кроме того, сеттеры могут вызвать проблемы владения ресурсами, если с ними не обращаться должным образом.

3
ответ дан 27 November 2019 в 22:07
поделиться

Любая достойная JVM (или компилятор) должна поддерживать встраивание. В C ++ компилятор встраивает геттеры и сеттеры. В Java JVM встраивает их во время выполнения после того, как они были вызваны "достаточно" раз. Не знаю насчет Д.

4
ответ дан 27 November 2019 в 22:07
поделиться

В C ++, когда включена оптимизация компилятора, геттеры и сеттеры могут быть «встроенными»: т. Е. Реализовываться с использованием тех же машинных инструкций, что и для прямого доступа к базовым данным элемента. .

2
ответ дан 27 November 2019 в 22:07
поделиться

Цитата из здесь Что касается языка программирования D

, я думаю, что DMD в настоящее время не может де-виртуализировать виртуальные геттеры и сеттеры. Виртуальные вызовы сами по себе немного медленнее, но они также не позволяют встраивать, поэтому последовательные стандартные оптимизации не могут быть выполнены. Так что, если такой доступ к атрибуту является виртуальным вызовом, и это происходит в «горячей» части кода, это может значительно замедлить ваш код. (если это происходит в неактивных частях кода, обычно это не имеет никакого эффекта. Вот почему Java Hot Spot в любом случае не нуждается в оптимизации всего вашего кода для создания очень быстрой программы).

Я поощрял Frits ван Боммел для улучшения возможностей девиртуализации LDC:

Теперь LDC может сделать это в нескольких очень простых ситуациях, но в большинстве случаев ситуация не меняется по сравнению с МДД. Со временем LLVM улучшится, так что эта ситуация может улучшиться сама по себе. Но внешний интерфейс тоже может что-то сделать с этим.

Вот документация по этой теме, некоторые старые , некоторые более современные :

3
ответ дан 27 November 2019 в 22:07
поделиться

В зависимости от ожидаемого развития вашего класса, get / setters могут загромождать ваш код, а не давать вам гибкость для расширения вашей реализации, не затрагивая клиентский код.

Часто я встречаются классы, которые используются как «контейнеры данных», у которых есть как геттер, так и сеттер для каждого члена. Это чепуха. Если вы не ожидаете, что при получении или установке члена будут запускаться какие-то «особые» функции, не пишите это.

Учитывая скорость машины, написание дополнительной абстракции будет стоить вашим клиентам больше денег.

Большинство компиляторов могут оптимизировать тривиальные геттеры / сеттеры, но как только вы объявляете их виртуальными (в C ++), вы платите за дополнительный поиск - часто это того стоит.

Get / setters могут загромождать ваш код, а не давать вам гибкости для расширения вашей реализации, не затрагивая клиентский код.

Часто я сталкиваюсь с классами, которые используются как «контейнеры данных», которые имеют как геттер, так и сеттер для каждого члена. Это чепуха. Если вы не ожидаете, что при получении или установке члена будут запускаться какие-то «особые» функции, не пишите это.

Учитывая скорость машины, написание дополнительной абстракции будет стоить вашим клиентам больше денег.

Большинство компиляторов могут оптимизировать тривиальные геттеры / сеттеры, но как только вы объявляете их виртуальными (в C ++), вы платите за дополнительный поиск - часто это того стоит.

Get / setters могут загромождать ваш код, а не давать вам гибкости для расширения вашей реализации, не затрагивая клиентский код.

Часто я сталкиваюсь с классами, которые используются как «контейнеры данных», которые имеют как геттер, так и сеттер для каждого члена. Это чепуха. Если вы не ожидаете, что при получении или установке члена будут запускаться какие-то «особые» функции, не пишите это.

Учитывая скорость машины, написание дополнительной абстракции будет стоить вашим клиентам больше денег.

Большинство компиляторов могут оптимизировать тривиальные геттеры / сеттеры, но как только вы объявляете их виртуальными (в C ++), вы платите за дополнительный поиск - часто это того стоит.

Часто я сталкиваюсь с классами, которые используются как «контейнеры данных», у которых есть как геттер, так и сеттер для каждого члена. Это чепуха. Если вы не ожидаете, что при получении или установке члена будут запускаться какие-то «особые» функции, не пишите это.

Учитывая скорость машины, написание дополнительной абстракции будет стоить вашим клиентам больше денег.

Большинство компиляторов могут оптимизировать тривиальные геттеры / сеттеры, но как только вы объявляете их виртуальными (в C ++), вы платите за дополнительный поиск, который часто стоит затраченных усилий.

Часто я сталкиваюсь с классами, которые используются как «контейнеры данных», у которых есть как геттер, так и сеттер для каждого члена. Это чепуха. Если вы не ожидаете, что при получении или установке члена будут запускаться какие-то «особые» функции, не пишите это.

Учитывая скорость машины, написание дополнительной абстракции будет стоить вашим клиентам больше денег.

Большинство компиляторов могут оптимизировать тривиальные геттеры / сеттеры, но как только вы объявляете их виртуальными (в C ++), вы платите за дополнительный поиск, который часто стоит затраченных усилий.

4
ответ дан 27 November 2019 в 22:07
поделиться

Я повторю Xtofl.

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

Если у вас есть побочные эффекты для получения или установки, обязательно используйте геттер или сеттер.

Но если нет, то написание геттеров и сеттеров просто загромождает код. Есть небольшое снижение производительности. В Java, если он выполняется всего несколько раз, штраф за перфорацию не имеет значения, а если он выполняется часто, он должен быть встроен, чтобы смягчить штраф. Так что я бы больше беспокоился о том, чтобы код было труднее читать.

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

1
ответ дан 27 November 2019 в 22:07
поделиться
Другие вопросы по тегам:

Похожие вопросы: