Оптимизация: убрать вычисление параметров у пустой функции
От: adb Россия  
Дата: 15.09.22 17:18
Оценка:
        int h1 = finalVal = (A() - 5 * C() + 20 * G() + 20 * M() - 5 * R() + T());
        push(QString("h1 = (A - 5 * C + 20 * G + 20 * M - 5 * R + T)"));
        push(QString("h1 = (%1 - 5 * %2 + 20 * %3 + 20 * %4 - 5 * %5 + %6) = %7")
                    .arg(A()).arg(C()).arg(G()).arg(M()).arg(R()).arg(T()).arg(h1));


Есть примерно такой код. И два способа использования.
1. Штатный должен выполнить все. Результатом будет вектор строк, который пойдет в ГУИ при нажатии мышки на пиксель (push — кидает строку в вектор).
2. Тестовый должен получить только finalVal для проверки. Создание объектов очень сильно убивает перформанс. Ибо в тестах нужно пройти каждый пиксель, каждой картинки. Т.е. он вызывается на много порядков чаще, чем при штатной работе.

Хочется без всяких if получить два кода. Пробовал сделать push пустым (думал в ней и сделаю if (template_parameter)). Но MSVC QString все равно создает и тут же сносит. Clang вроде как чистит все в ноль.

Есть ли какой-нибудь универсальный метод сделать нужное без макросов и лишних If?
Re: Оптимизация: убрать вычисление параметров у пустой функции
От: DiPaolo Россия  
Дата: 15.09.22 17:22
Оценка:
adb>Есть ли какой-нибудь универсальный метод сделать нужное без макросов и лишних If?

if constexpr


        constexpr bool isDebug = true;

        int h1 = finalVal = (A() - 5 * C() + 20 * G() + 20 * M() - 5 * R() + T());

        if constexpr (!isDebug) {
            push(QString("h1 = (A - 5 * C + 20 * G + 20 * M - 5 * R + T)"));
            push(QString("h1 = (%1 - 5 * %2 + 20 * %3 + 20 * %4 - 5 * %5 + %6) = %7")
                        .arg(A()).arg(C()).arg(G()).arg(M()).arg(R()).arg(T()).arg(h1));
        }
Патриот здравого смысла
Re: Оптимизация: убрать вычисление параметров у пустой функции
От: sergii.p  
Дата: 15.09.22 18:47
Оценка:
Здравствуйте, adb, Вы писали:

adb>Есть ли какой-нибудь универсальный метод сделать нужное без макросов и лишних If?


похоже, вам нужно что-то типа lazy. В шарпе он есть, в С++ нет, но можно сделать самому.

template<typename T>
struct lazy {
    using Func = std::function<T()>;
    lazy(Func&& f) : funcOrVal { std::move(f) } {}
    operator T() {
        if(funcOrVal.index() == 0){
            funcOrVal = std::get<Func>(funcOrVal)();
        }
        return std::get<T>(funcOrVal);
    }
    private:
        std::variant<Func, T> funcOrVal;
};


но тогда надо принимать lazy везде, где вы принимаете QString. Ну и принимать все риски отложенных вычислений.
Re[2]: Оптимизация: убрать вычисление параметров у пустой функции
От: adb Россия  
Дата: 15.09.22 18:52
Оценка:
Здравствуйте, sergii.p, Вы писали:

SP>Здравствуйте, adb, Вы писали:


adb>>Есть ли какой-нибудь универсальный метод сделать нужное без макросов и лишних If?


SP>похоже, вам нужно что-то типа lazy. В шарпе он есть, в С++ нет, но можно сделать самому.


Прикольно. Полезный инструмент. Но я тут подумал, наверно проще будет просто переопределить QString. Сделать его параметром шаблона и подсовывать класс пустышку. Попробую так сделать.
Re[2]: Оптимизация: убрать вычисление параметров у пустой функции
От: Андрей Тарасевич Беларусь  
Дата: 15.09.22 21:10
Оценка:
Здравствуйте, sergii.p, Вы писали:

SP>похоже, вам нужно что-то типа lazy. В шарпе он есть, в С++ нет, но можно сделать самому.


`std::async` c `std::launch::deferred` — готовый lazy.
Best regards,
Андрей Тарасевич
Re: Оптимизация: убрать вычисление параметров у пустой функции
От: B0FEE664  
Дата: 15.09.22 22:46
Оценка:
inline constexpr bool do_push = условие;

inline bool Push(QString&& str)
{
  push(std::move(str)); // если push ваша, пусть она возвращает всегда true, тогда эта функция не нужна
  return true;
}

...

        int h1 = finalVal = (A() - 5 * C() + 20 * G() + 20 * M() - 5 * R() + T());
        do_push && Push(QString("h1 = (A - 5 * C + 20 * G + 20 * M - 5 * R + T)"));
        do_push && Push(QString("h1 = (%1 - 5 * %2 + 20 * %3 + 20 * %4 - 5 * %5 + %6) = %7")
                         .arg(A()).arg(C()).arg(G()).arg(M()).arg(R()).arg(T()).arg(h1));


или тоже самое с функцией Push() вместо глобальной константы:

inline bool Push(QString&& str)
{
  push(std::move(str));
  return true;
}

inline /*constexpr*/ bool Push() { return условие; }


...

        int h1 = finalVal = (A() - 5 * C() + 20 * G() + 20 * M() - 5 * R() + T());
        Push() && 
        Push(QString("h1 = (A - 5 * C + 20 * G + 20 * M - 5 * R + T)"));
        Push() &&
        Push(QString("h1 = (%1 - 5 * %2 + 20 * %3 + 20 * %4 - 5 * %5 + %6) = %7").arg(A()).arg(C()).arg(G()).arg(M()).arg(R()).arg(T()).arg(h1));
И каждый день — без права на ошибку...
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.