C++ 中 Bool functor 的优化

来源:互联网 发布:西北师大知行学院附近宾馆 编辑:程序博客网 时间:2024/05/16 08:16

原以为足够现代的编译器的优化能力很强,看来我是高估了。GCC 没测过,VC 2008 刚刚被证实了。

    pair<int,int> x(rand(), rand()), y(rand(), rand());

   for (int i = 0; i < 1000; ++i)

   {

      if (x < y)

         x.first += y.second, y.second -= x.second;

   }

 

// pair.< 的定义

template<class _Ty1, class _Ty2> inline

bool operator<(const pair<_Ty1, _Ty2>& _Left,

               const pair<_Ty1, _Ty2>& _Right)

{  // test if _Left < _Right for pairs

   return (_Left.first < _Right.first ||

      !(_Right.first < _Left.first) && _Left.second < _Right.second);

}

主要是看其中的 if (x < y) 会被优化成什么样子。我原估计的是会在 inline 展开之后,将函数的返回值直接映射到true/false分支,没想到让我大失所望:

 

; 93   :  {
; 94   :   if (x < y)

  003d2 8b 45 e4  mov  eax, DWORD PTR _x$[ebp]
  003d5 3b 45 ec  cmp  eax, DWORD PTR _y$[ebp]
  003d8 7c 1c   jl  SHORT $LN71@TestBoolOp
  003da 8b 4d ec  mov  ecx, DWORD PTR _y$[ebp]
  003dd 3b 4d e4  cmp  ecx, DWORD PTR _x$[ebp]
  003e0 7c 08   jl  SHORT $LN70@TestBoolOp
  003e2 8b 55 e8  mov  edx, DWORD PTR _x$[ebp+4]
  003e5 3b 55 f0  cmp  edx, DWORD PTR _y$[ebp+4]
  003e8 7c 0c   jl  SHORT $LN71@TestBoolOp
$LN70@TestBoolOp:
  003ea c7 85 40 ff ff
 ff 00 00 00 00  mov  DWORD PTR tv84[ebp], 0
  003f4 eb 0a   jmp  SHORT
$LN68@TestBoolOp
$LN71@TestBoolOp:
  003f6 c7 85 40 ff ff
 ff 01 00 00 00  mov  DWORD PTR tv84[ebp], 1
$LN68@TestBoolOp:
  00400 0f b6 85 40 ff
 ff ff   movzx  eax, BYTE PTR tv84[ebp]
  00407 85 c0   test  eax, eax
  00409 74 12   je  SHORT
$LN1@TestBoolOp

; 95   :    x.first += y.second, y.second -= x.second;

  0040b 8b 4d e4  mov  ecx, DWORD PTR _x$[ebp]
  0040e 03 4d f0  add  ecx, DWORD PTR _y$[ebp+4]
  00411 89 4d e4  mov  DWORD PTR _x$[ebp], ecx
  00414 8b 55 f0  mov  edx, DWORD PTR _y$[ebp+4]
  00417 2b 55 e8  sub  edx, DWORD PTR _x$[ebp+4]
  0041a 89 55 f0  mov  DWORD PTR _y$[ebp+4], edx
$LN1@TestBoolOp:

; 96   :  }

  0041d eb a1   jmp  SHORT $LN3@TestBoolOp
$LN2@TestBoolOp:

我原乐观地以为编译器的代码不会出现紫色背景的代码,而红色背景的跳转会直接到黄色处,绿色背景的跳转会跳过黄色。是我对编译器要求太高了吗?可是,这样functor在排序、查找等应用中是随处可见的,要浪费多少CPU 啊!真的是硬件水平高了,软件就可以随意挥霍了吗?

与其这样,类似 std::sort 这样的函数还不如不要 inline Compare Functor,直接使用 qsort 算了,还不用那么多的代码膨胀。感觉这样的代码膨胀带来的效益太少了,好像某权威测试对 std::sort 和 qsort  的对简单数据的排序对比说明它仅比 qsort 快 20%~30%。可是在一个典型应用中它带来的代码膨胀恐怕 2000%~3000%都有吧。

现在用习惯了 C++ 的 Template,不用它就感觉不舒服。但是经常一个小规模的 C++ 程序编译出的执行程序就有2~3M,这还是优化过,去掉所有调试信息的。真不知道如何办好!