19

最近,在一次讨论中,一位程序员同事要求我做一些代码更改。我有类似的东西:

if( mystring.size() == 0)
    // do something
else
    // do something else 

讨论是关于使用mystring.empty()来验证字符串是否为空。现在,我同意它可以说string.empty()是更冗长和可读的代码,但它有任何性能优势吗?

我做了一些挖掘,发现这两个与我的问题有关的答案:

这两个答案都支持我的说法,即string.empty()string.size() == 0.

我仍然想确定,是否有任何实现string保持内部布尔标志来验证字符串是否为空?

还是某些实现使用的其他方式会使我的主张无效?

4

2 回答 2

35

该标准定义empty()如下:

bool empty() const noexcept;
返回:size() == 0。

您很难找到不这样做的东西,并且由于两者都是恒定时间操作,因此任何性能差异都可以忽略不计。我希望两者都能在任何合理的实现上编译成完全相同的程序集。

这就是说,empty()是明确和明确的。为了可读性,您应该更喜欢它size() == 0(或!size())。

于 2013-07-09T03:59:46.660 回答
7

现在,这是一件非常微不足道的事情,但我会尽量详尽地介绍它,所以无论同事提出的任何论点都不太可能让你感到惊讶......

像往常一样,如果分析证明你真的需要关心,测量:可能会有差异(见下文)。但在一般代码审查情况下,未证明有问题的慢代码,突出的问题是:

  • 在其他一些容器(例如 C++ 03列表但不是 C++11)中,size()效率低于容器类型可能不同的模板)无需进行任何更改即可保持效率。empty()empty()size()

  • 是否反映了一种更自然的方式来构思测试?- 不仅仅是你碰巧首先想到的,或者size()因为你不习惯使用empty(),而是当你 100% 专注于周围的代码逻辑时,是否size()empty()更适合?例如,可能是因为它是几个测试之一,size()并且您喜欢保持一致性,或者因为您正在实施传统上以大小表示的著名算法或公式:保持一致可能会减少验证实施时的心理噪音/努力公式。

大多数情况下,上述因素无关紧要,在代码审查中提出问题确实是浪费时间。

可能的性能差异

虽然标准要求功能等效,但某些实现可能会以不同的方式实现它们,尽管我一直在努力并且到目前为止未能记录一个特别合理的这样做的理由。

对于影响实现选择的其他函数的行为,C++11 比 C++03 有更多约束:data()必须以 NUL 终止(过去只是c_str()),[size()]现在是有效索引并且必须返回对 NUL 字符的引用。由于各种微妙的原因,这些限制使得它更有可能empty()不会比size().

无论如何 - 衡量你是否需要关心。

于 2013-07-09T05:11:21.297 回答