@gth-other

Почему вызов метода класса гораздо медленее вызова обычной функции и как это исправить?

Есть такой код, разделенный на несколько файлов:

main.cpp
#include <iostream>
#include "T.hpp"


unsigned long long sum(unsigned long long n0, unsigned long long n1) {
    return n0 + n1;
}


int main() {
    long long time_start = time(nullptr);

    unsigned long long result = 0;

    for (long long i = 0; i < 20000000000; i = i + 1) {
        result = T::sum(result, i);
    }

    std::cout << result << std::endl;

    std::cout << time(nullptr) - time_start << std::endl;

    return 0;
}

T.hpp
class T {
public:
    static unsigned long long sum(unsigned long long n0, unsigned long long n1);
};

T.cpp
#include "T.hpp"


unsigned long long T::sum(unsigned long long int n0, unsigned long long int n1) {
    return n0 + n1;
}


Если считать сумму чисел от 1 до двадцати миллиардов функцией sum, то сумма считается за несколько секунд. Если считать функцией T::sum, то сумма считается за несколько десятков секунд. Разница десятикратная. Вопрос: почему и как исправить?
  • Вопрос задан
  • 142 просмотра
Решения вопроса 2
wataru
@wataru Куратор тега C++
Разработчик на С++, экс-олимпиадник.
Подозреваю, что дело в оптимизаторе. В первом примере компилятор понимает, что цикл ничего не делает и вырезает его весь нафиг. Во втором же случае, разделение на файлы не позволило оптимизатору убрать цикл. Можно покрутить опциями оптимизатора, что бы была кросс-модульная оптимизация (не помню правильное название), но в итоге вы будете сравнивать пустоту с пустотой.

Правильнее добавить в тестируемую функцию какую-то работу. Тогда вы будуте действительно сравнивать вызов функции и метода. Или отключить всю оптимизацию.
Ответ написан
vt4a2h
@vt4a2h Куратор тега C++
Senior software engineer (C++/Qt/boost)
Дело тут ещё и в методах измерения. По-хорошему, нужно взять любой тестовый фреймворк, будь-то google benchmark или там catch2, который позволяет осуществлять замеры производительности. В нём создать два бенчмарка и смотреть на разницу. Если она будет какая-то существенная, то брать профилировщик, правильно компилировать проект и смотреть что занимает больше всего времени выполнения.
А уже после этого можно играть с флагами и смотреть какой код генерируется в обоих случаях. Можно и до в этом конкретном случае.

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

PS
Но у вас скорее всего и правда оптимизатор код выкидывает в первом случае всё считается во время компиляции, а функция встраивается. Во втором случае это сложнее.
Вот тут ещё можете посмотреть какой код генерируется и с флагами поиграться: https://www.godbolt.org/
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы