使用 std::find 会影响性能

SPM*_*PMP -3 c++ templates c++11 c++14

我有以下代码来检查某个值是否属于值列表。例如:contains({1,2,3},3). 几乎总是,我可以写一堆if-elses。该方法会对性能造成多大影响contains?有办法避免这种情况吗?

template<typename T1,typename T2>
std::enable_if_t<std::is_same<std::initializer_list<T2>,T1>::value, bool> contains(const T1 &container,const T2 &item)
{
    return(std::find(container.begin(),container.end(),item)!=container.end());
}
Run Code Online (Sandbox Code Playgroud)

Ser*_*eyA 5

有了知道如何展开循环的良好优化编译器,您最终将获得几乎相同的程序集和相同的性能。

证明:

find_if

#include <algorithm>
#include <initializer_list>

template<typename T1,typename T2>
bool contains(const T1 &container,const T2 &item) {
    return(std::find(container.begin(),container.end(),item)!=container.end());
}

bool foo(int a, int b, int c, int d, int e) {
  return contains(std::initializer_list<int>({a, b, c, d, e}), 5);
}
Run Code Online (Sandbox Code Playgroud)

集会:

foo(int, int, int, int, int):
        cmpl    $5, %edi        #, a
        je      .L6 #,
        cmpl    $5, %esi        #, b
        je      .L6 #,
        cmpl    $5, %edx        #, c
        je      .L6 #,
        cmpl    $5, %ecx        #, d
        je      .L6 #,
        cmpl    $5, %r8d        #, e
        sete    %al     #, D.75010
        ret
Run Code Online (Sandbox Code Playgroud)

if-else

bool foo(int a, int b, int c, int d) {
  if (a == 5)
    return true;
  else if (b == 5)
    return true;
  else if (c == 5)
    return true;
  else if (d == 5)
    return true;
  return false;
}
Run Code Online (Sandbox Code Playgroud)

集会:

foo(int, int, int, int):
        cmpl    $5, %edx        #, c
        sete    %dl     #, D.74611
        cmpl    $5, %ecx        #, d
        sete    %al     #, D.74611
        orl     %edx, %eax        # D.74611, D.74611
        cmpl    $5, %esi        #, b
        sete    %dl     #, D.74611
        orl     %edx, %eax        # D.74611, D.74611
        cmpl    $5, %edi        #, a
        sete    %dl     #, D.74611
        orl     %edx, %eax        # D.74611, D.74611
        ret
Run Code Online (Sandbox Code Playgroud)