if/else优化测试结果令人震惊

if/else optimization test results ambigious

本文关键字:测试结果 else 优化 if      更新时间:2023-10-16

我在代码中测试了三种场景,其中我想优化掉if语句(该值在运行时只设置一次,然后检查了数百万次)我评估的三种方法如下

  1. A template bool binded at compile time
  2. A static bool initialized on first call
  3. A bool member variable which gets initialized at construction

结果有点不直观,即模板版本花费了相同的时间,但静态成员变量方法更快。有人能解释一下原因吗?

结果(多次运行一致)

elapsed time: 0.230933 4501s
elapsed time: 0.212918 4501s
elapsed time: 0.230512 4501s

示例代码在这里

#ifndef TEST_H_
#define TEST_H_
#include <math.h>
#include <iostream>
template<bool Condition>
class Test {
public:
    Test() :
        signal_(0.0), condition_(false), max_truncation_(12000.00) {
    }
    ~Test() {
    }
    void CalculateTestingTemplate(double& i);
    void CalculateTestingStatic(double& i);
    void CalculateTestingMemberVariable(double& i);
private:
    double signal_;
    double condition_;
    double max_truncation_;
};
template<bool Condition>
void Test<Condition>::CalculateTestingTemplate(double& i) {
    i++;
    if (Condition) {
        if (fabs(i) > max_truncation_) {
            i = 0;
        }
    }
    if (Condition) {
        if (fabs(i) > max_truncation_) {
            i = 0;
        }
    }
    if (fabs(i) > max_truncation_) {
        i = 0;
    }
};
template<bool Condition>
void Test<Condition>::CalculateTestingStatic(double& i) {
    i++;
    static bool condition = condition_;
    if (condition) {
        if (fabs(i) > max_truncation_) {
            i = 0;
        }
    }
    if (condition) {
        if (fabs(i) > max_truncation_) {
            i = 0;
        }
    }
    if (fabs(i) > max_truncation_) {
        i = 0;
    }
};

template<bool Condition>
void Test<Condition>::CalculateTestingMemberVariable(double& i) {
    i++;
    if (condition_) {
        if (fabs(i) > max_truncation_) {
            i = 0;
        }
    }
    if (condition_) {
        if (fabs(i) > max_truncation_) {
            i = 0;
        }
    }
    if (fabs(i) > max_truncation_) {
        i = 0;
    }
};
#endif // TEST_H_

以及在环路中计时(-O3)的主要功能

#include <ctime>
#include <chrono>
#include "test.h"
using namespace std;
int main(int argc, char const *argv[]) {
    Test<false>* object = new Test<false>();
    int iteration = 90000000;
    std::chrono::time_point<std::chrono::system_clock> start, end;
    start = std::chrono::system_clock::now();
    int i = 0;
    double j = 0;
    for(; i<iteration;i++)
    {
        object->CalculateTestingTemplate(j);
    }
    end = std::chrono::system_clock::now();
    std::chrono::duration<double> elapsed_seconds = end - start;
    std::cout << "elapsed time: " << elapsed_seconds.count() << " " << j << "sn";
    start = std::chrono::system_clock::now();
    i = 0;
    j = 0;
    for(; i<iteration;i++)
    {
        object->CalculateTestingStatic(j);
    }
    end = std::chrono::system_clock::now();
    elapsed_seconds = end - start;
    std::cout << "elapsed time: " << elapsed_seconds.count() << " " << j << "sn";

    start = std::chrono::system_clock::now();
    i = 0;
    j = 0;
    for(; i<iteration;i++)
    {
        object->CalculateTestingMemberVariable(j);
    }
    end = std::chrono::system_clock::now();
    elapsed_seconds = end - start;
    std::cout << "elapsed time: " << elapsed_seconds.count() << " " << j << "sn";

    return 0;
}

您的模板测试可能比预期的慢,因为它首先运行,因此会遇到缓存未命中,而其他测试不会遇到缓存未中,因为模板测试已经将数据带入缓存。