C和C++编译器通常会对函数比较进行优化吗?
例如,此页面建议,在某些标准库实现中,C++中std :: lists的size
函数可能具有线性复杂度O(N)(这对于链表是有意义的)。
但在这种情况下,如果myList
是一个巨大的列表,像这样的语句会怎么样?
if (myList.size() < 5) return 1;
else return 2;
size()函数是否会查找并计数所有N个列表成员,还是在找到5个成员后就被优化为短路?
C和C++编译器通常会对函数比较进行优化吗?
例如,此页面建议,在某些标准库实现中,C++中std :: lists的size
函数可能具有线性复杂度O(N)(这对于链表是有意义的)。
但在这种情况下,如果myList
是一个巨大的列表,像这样的语句会怎么样?
if (myList.size() < 5) return 1;
else return 2;
size()函数是否会查找并计数所有N个列表成员,还是在找到5个成员后就被优化为短路?
size()
被内联,那么可能存在这种可能性,但是为了执行优化,编译器必须:
unsigned
不会,因为 UINT_MAX+1
< UINT_MAX
)。 - MSalters实际上,在C++11中,std::list
已经进行了优化,size()
的时间复杂度为常数。
对于C++03来说,size()
的时间复杂度确实是线性的,因为它需要每次都统计元素个数。
size()函数会查找并计算所有N个列表成员,还是在找到5个成员后就停止计算?
我从未见过这种优化在实践中发生过。虽然这是合法的,但我怀疑任何编译器都没有实现类似的优化。
length
。 - Fred Foolength xs < k
将遍历整个列表,我不知道有哪种实现可以快捷地完成它。您可以使用 genericLength xs < k
和适当的惰性数字类型来进行快捷操作。或者使用重写规则 forall k xs. length xs < k = if k < 1 then False else null (drop (k-1) xs)
,但这是您自己的工作,而不是编译器的工作。 这将更改例如 length (1:2:undefined) < 2
的行为,所以编译器不能提供它。 - Daniel FischermyList.size()函数本身没有办法为你使用的目的进行编译,因此它将确定整个大小。为了获得您建议的优化,您需要一个专用的谓词函数,而不是通用的size()
,类似于bool sizeLessThan(int);
。
不行你在询问编译器是否可以使函数根据其结果的使用方式而表现出不同的行为。这只有在调用者和函数同时被编译在一起的内联函数中才有可能实现。除此之外,似乎很难达成。
size
内联,这可能是有潜力的,但我认为很难发现它可以打破正在增加计数器的循环。 - Rupsize()
的O(1)复杂度,但它确实建议这样做,并且实现起来很简单。如果您的实现没有跟踪容器中元素的数量(您可以通过阅读<list>
头文件轻松检查此问题),那么我会感到惊讶。 - David Rodríguez - dribeassize()
这种情况来说,它是一个特例,因为作为一个模板,编译器有函数的定义,并且有一些很小的可能性可以弄清楚它。总的来说,编译器无法访问函数的定义,优化的机会更加困难。 - David Rodríguez - dribeas