Передавать ли в метод указатель на Worker или хранить его как член класса

в 18:07, , рубрики: c++, высокая производительность

Давно беспокоил этот вопрос, потому что часто сложные классы приходится разделять на более мелкие

class Service1
{
public:
    void doWork(Complex* complex)
    {
        complex->doWork();
    }
};

class ServiceN
{
public:
    void doWork()
    {
        _complex->doWork();
    }
private:
    Complex* _complex
};

class Complex
{
...
private:
    friend class Service1;
    Service1 service1;
...
    friend class Service2;
    ServiceN servicen;
};


Давайте разберемся. Используем компилятор GCC 4.9 и утилиту Callgrind и оптимизациями копилятора для Профилировнаия.

#include <iostream>

using namespace std;

class Worker
{
public:
    void work()
    {
        printf("work for loven");
    }
    void freeWork()
    {

        printf("work for foodn");
    }
};

static Worker worker;

void freeWork(Worker* worker)
{
    for(int i = 0; i < 10000; ++i)
        worker->freeWork();
}

void work()
{
    for(int i = 0; i < 10000; ++i)
        ::worker.work();
}

int main()
{
    Worker worker;

    for(int i = 0; i < 100; ++i) { // дополнительный цикл, для исключения оптимизации
        ::freeWork(&worker);
        ::work();
    }
    return 0;
}

Результаты теста на скринах

image

Количество инструкций процессора

image

Видим, что в случае когда мы передаем указатель на Worker в функцию, то CPU тратится на 4 инструкции больше.

Однако, при чтобы инициализировать член класса Complex в конструкторе, CPU читает столько же или больше инструкций, к тому же мы тратим 4 или 8 байт на хранение указателя как член класса.

Вывод

Разница почти не наблюдается, поэтому делайте как вам удобно, однако самый лучший вариант самим провести подобный тест.

Автор: Жрец

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js