Скорость переадресации функций

181
29 марта 2019, 21:10

Что лучше в плане быстродействия: вызывать члены класса, наследованные из другого класса, или вызывать члены класса, полученные из хранящегося в классе объекта другого класса?

struct A {
    void foo() {
        // not inline code
        // ...
    }
};
struct B : A {
};
struct C {
    void foo() {
        return a.foo();
    }
    A a;
};

int main() {
    B b;
    C c;
    b.foo(); // ?
    c.foo(); // ?
}
Answer 1

После того, как по коду проедется оптимизирующий компилятор, это будет все равно...

И еще запомните фразу Кнута - что корень всех бед в преждевременной оптимизации. Не надо на этом уровне начинать оптимизировать - это напоминает попытки алкоголика, пропивающего все, что можно, сэкономить на спичках :)

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

P.S. A priori в вашем конкретном случае b.foo() превратится в вызов A::foo(), а c.foo() при минимальной же оптимизации - тоже в A::foo(). Без оптимизации будет вызов из вызова.

Answer 2

При вызове нестатического метода класса в него неявно передается указатель на экземпляр этого класса this. Соответственно при вызове может иметь место некоторый оверхед на модификацию указателя в зависимости от организации классов. Отдельная проблема с виртуальным наследованием - в этом случае для получения указателя на экземпляр класса придется лезть внутрь текущего, то бишь лишний редирикт. Например:

struct C
{
   A a;
   void foo(void)
   {
      return a.foo(); // значение A * будет таким же, как и С * this
   }
};
struct C
{
   int x;
   A a;
   void foo(void)
   {
      return a.foo(); // значение A * будет вычисляться, как С * this со смещением 4 байта
   }
};
struct B : A // значение A * будет таким же, как и С * this
{};
struct B : NonEmptyFoo, A // значение A * будет вычисляться, как и С * this со смещением sizeof(NonEmptyFoo) байт
{};
struct B : virtual A // значение A * будет храниться в экземпляре класса, как и this->vptr_a
{};
READ ALSO
Найти все простые числа в диапазоне [A; B]

Найти все простые числа в диапазоне [A; B]

Найти все простые числа в диапазоне от А до В (1 <= A <= B <= 10^12 ), при условии, что В - А >= 10 ^ 6Уже 4 день ломаю над этим голову

233
Шифр Виженера(не работает)

Шифр Виженера(не работает)

решил сделать сам Шифратор/Дешифратор Виженера, но столкнулся с какой-то не понятной проблемой:

159
Исходный код Yandex speller

Исходный код Yandex speller

Где я могу найти исходный код Yandex speller, обыскал весь интернет, но не нашел, еще один вопрос есть ли yandex speller в качестве библиотеки для java?

173
Java, парсинг строки

Java, парсинг строки

Есть строка типа HaT523HaT524HaT525Подскажите, пожалуйста, как можно разбить эту строку так:

191