最近,在一次讨论中,一位程序员要求我做一些代码更改。我有类似的东西:
if( mystring.size() == 0)
// do something
else
// do something else
讨论是关于使用mystring.empty()
来验证字符串是否为空。现在,我同意可以认为string.empty()
是更详细和可读的代码,但是它有任何性能上的好处吗?
我做了一些挖掘,发现这2个答案与我的问题有关:
与string.empty()
相比,这两个答案都支持我的主张string.size() == 0
更具可读性,并没有提供任何性能优势。
我仍然想确定,如果有string
的任何实现保留内部布尔标志来验证字符串是否为空?
或者某些实现使用其他方法,这会使我的声明无效?
答案 0 :(得分:30)
标准定义empty()
,如下所示:
bool empty()const noexcept;
返回:size()== 0。
你很难找到不能做到这一点的东西,任何性能差异都可以忽略不计,因为它们都是恒定的时间操作。我希望在任何合理的实现上都能编译到完全相同的程序集。
尽管如此,empty()
清晰而明确。为了便于阅读,您应该优先于size() == 0
(或!size()
)。
答案 1 :(得分:7)
现在,这是一个非常微不足道的事情,但我会尽力覆盖它,所以无论同事提出什么样的论据都不会让你感到意外......
像往常一样,如果分析证明你真的真的必须关心,那么衡量:可以是一个区别(见下文)。但是对于未经证实有问题的慢代码的一般代码审查情况,未解决的问题是:
在其他一些容器中(例如C ++ 03列表而不是C ++ 11),size()
效率低于empty()
,导致一些编码提示更喜欢{{1}通常超过empty()
,以便如果有人需要稍后切换容器(或将处理概括为容器类型可能不同的模板),则不需要进行任何更改以保持效率。
是否反映出一种更自然的方式来构思测试? - 不仅仅是你第一次想到的,或size()
,因为你不习惯使用size()
,但是当你100%专注于周围的代码逻辑时,{{1} }或empty()
更适合?例如,也许是因为它是size()
的几个测试中的一个并且你喜欢具有一致性,或者因为你正在实现一个传统上用大小来表达的着名算法或公式:保持一致可能会减少心理噪音/努力根据公式验证实施情况。
大多数情况下,上述因素都是微不足道的,在代码审查中提出问题实际上是浪费时间。
可能的效果差异
虽然标准要求功能等同,但某些实现可能以不同的方式实现它们,尽管我一直在努力,但迄今为止未能记录这样做的特别合理的理由。
C ++ 11比其他影响实现选择的函数的行为有比C ++ 03更多的约束:empty()
必须NUL终止(以前只是size()
),{{1}现在是一个有效的索引,必须返回对NUL字符的引用。由于各种微妙的原因,这些限制使data()
更有可能不会比c_str()
更快。
无论如何 - 衡量你是否需要关心。