std::is_same对代码的性能有影响吗?

3
is_same 对代码性能是否有影响?我在代码中多次使用它来检查是否必须使用 std::lessstd::greater 并根据它们检索特定值。我的测试足以证明 std::is_same 在我的情况下实际上没有影响代码性能吗?
这个代码比那个复杂得多,我必须使用模板。我尽可能地模仿了使用 is_same 的位置。
我使用了编译器选项 -O3 编译并运行了代码。
#include <iostream>
#include <vector>
#include <chrono> 

using namespace std::chrono; 
using namespace std;

template<typename T>
int returnVal(T compare) {
    std::vector<int> v = {1,2,3,4};
    if(std::is_same<T,std::greater<int>>::value) {
        return std::min(v[0], v[1], compare);
    } else {
        return std::min(v[2], v[3], compare);
    }
}

int returnValNoTemplate(bool b) {
    std::vector<int> v = {1,2,3,4};
    if(b == true) {
        return std::min(v[0], v[1]);
    } else {
        return std::min(v[2], v[3]);
    }
}


int main()
{   
    
    for(int i = 0; i < 10; i++) {
      auto start = high_resolution_clock::now(); 
      for(int i  = 0; i < 100000;++i) {
        int x = returnVal(std::greater<int>());
      }
    
      auto stop = high_resolution_clock::now();
      auto duration = duration_cast<microseconds>(stop - start); 
      cout <<"is_same duration:" <<  duration.count() << "\n" << endl; 
    
      auto start1 = high_resolution_clock::now(); 
      for(int i  = 0; i < 100000;++i) {
       int y = returnValNoTemplate(true);
      }
      auto stop1 = high_resolution_clock::now();
      auto duration1 = duration_cast<microseconds>(stop1 - start1); 
      cout <<"No template duration:" <<  duration1.count() << "\n" << endl; 
    }

    return 0;
}

R1:is_same持续时间:4052,无模板持续时间:4041

R2:is_same持续时间:3954,无模板持续时间:3950

R3:is_same持续时间:3963,无模板持续时间:3973

R4:is_same持续时间:4008,无模板持续时间:4048

R5:is_same持续时间:3948,无模板持续时间:3998

R6:is_same持续时间:4130,无模板持续时间:4036

R7:is_same持续时间:3932,无模板持续时间:3948

R8:is_same持续时间:4183,无模板持续时间:4088

R9:is_same持续时间:4731,无模板持续时间:5062

R10:is_same持续时间:4018,无模板持续时间:4887


#交换测试#

R1:无模板持续时间:5729,is_same持续时间:5474

R2:无模板持续时间:3988,is_same持续时间:4039

R3:无模板持续时间:3996,is_same持续时间:4114

R4:无模板持续时间:4063,is_same持续时间:4068

R5:无模板持续时间:3979,is_same持续时间:4096

R6:无模板持续时间:4159,is_same持续时间:4020

R7:无模板持续时间:3990,is_same持续时间:4086

R8:无模板持续时间:4001,is_same持续时间:4055

R9:无模板持续时间:4048,is_same持续时间:4088

R10:无模板持续时间:4070,is_same持续时间:4017


1
如果它真的这样做了,我会感到惊讶。我一直认为这些检查是在编译时发生的,并且函数是生成来处理每种类型的。 - smac89
2
在测试性能时,非常重要的一点是使用已开启编译器优化(也称为“发布版本”)的构建代码进行测试。大多数编译器的默认设置都是进行未优化的调试构建。未优化的构建速度非常慢,而且通常存在着优化构建可以完全消除的问题。不要对调试构建进行基准测试,这没意义,并且根本不能反映最终发布构建的真实性能。 - Jesper Juhl
2
从理论上讲,模板版本可能表现更好,因为std::is_same在编译时解析。由于您正在将常量值传递给另一个版本,我预计编译器在这种情况下会为两者生成相同的汇编代码。无论哪种方式,我怀疑差异都几乎无法检测到。 - Miles Budnek
1
std::is_same是一个编译时常量,就好像你在它的位置上写了 true 或者 false。因此,性能特性将与使用字面值 truefalse 完全相同 -- 即使使用 -O0 编译器也会消除条件和 false 分支(gcc和clang都这样做)。 - cdhowie
1
交换测试的顺序可能会改变结果。 - Alan Birtles
1个回答

2

std::is_same是一种编译时检查,它使用两种不同的模板形式实现。其中一个模板包含1个类型,另一个模板包含2个类型。

std::is_same<T, T> //If the compiler resolves to this it is the same type;
std::is_same<T, U> //If the compiler resolves to this it is 2 types;

实现返回一个类型,然后进行转换为bool,解析为true或false,从而生成代码中的一条路径。

@SergeyA 我尝试进一步澄清。 - yugami

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接