19

C 和 C++ 编译器通常会优化与函数的比较吗?

例如,此页面建议sizeC++ 中 std::lists 上的函数在某些标准库实现中可能具有 O(N) 的线性复杂度(这对链表有意义)。

但在那种情况下,如果myList是一个巨大的列表,这样的东西会做什么?

    if (myList.size() < 5) return 1;
    else return 2;

size() 函数会查找并计算所有 N 个列表成员,还是会在找到 5 个成员后优化为短路?

4

4 回答 4

15

理论上,如果被内联,则存在这种可能性size(),但要执行优化,编译器必须

  1. 检测您正在专门测试“小于”条件
  2. 证明循环(假设存在一个用于讨论的目的)导致变量单调增加
  3. 证明循环体没有可观察到的副作用

恕我直言,这是一大堆东西,它包括在其他情况下也不是“明显有用”的功能。请记住,编译器供应商的资源有限,因此必须有充分的理由来实现这些先决条件并让编译器将所有部分组合在一起以优化这种情况。

看到即使这对某人来说是一个性能问题,这个问题也可以在代码中轻松解决,我不觉得会有这样的理由。所以不,通常你不应该期望这样的情况得到优化。

于 2012-05-11T11:24:01.883 回答
11

实际上,在 C++11 中,std::list经过优化并size()以恒定时间返回。

对于 C++03,size()确实是在线性时间中运行的,因为它每次都需要计算元素。

size() 函数会查找并计算所有 N 个列表成员,还是会在找到 5 个成员后优化为短路?

在实践中从未见过这种优化。虽然这当然是合法的,但我怀疑是否有任何编译器实际上实现了这样的东西。

于 2012-05-11T11:21:00.333 回答
2

myList.size() 函数本身无法为您使用它的目的进行编译,因此它将确定整个大小。为了获得您建议的优化,您需要一个专用的谓词函数而不是通用的size(),例如bool sizeLessThan(int);.

于 2012-05-11T11:22:15.470 回答
2

您是在询问编译器是否可以根据其结果的使用方式使函数表现不同。这只能对调用者和函数将同时编译在一起的内联函数进行。除此之外的任何事情似乎都有些牵强。

于 2012-05-11T17:31:03.470 回答