Recently, during a discussion I was asked by a fellow programmer to do some code changes. I had something like:
if( mystring.size() == 0)
// do something
else
// do something else
The discussion was regarding the use of mystring.empty()
to validate if the string is empty. Now, I agree that it can be argued that string.empty()
is more verbose and readable code, but are there any performance benefits to it?
I did some digging and found these 2 answers pertaining to my question:
Both the answers buttress my claim that the string.empty()
is just more readable and doesn't offer any performance benefits, compared to string.size() == 0
.
I still want to be sure, if there are any implementations of string
that keep an internal boolean flag to validate if a string is empty or not?
Or there are other ways that some implementations use, that would nullify my claim??
Consider Real World Optimization String x = ""; In my test, there was no noticeable difference. Sometimes string. Empty was faster and sometimes the empty string was faster.
For an empty string, length is 0.
true if the value parameter is null or an empty string (""); otherwise, false .
std::string::clear in C++ The string content is set to an empty string, erasing any previous content and thus leaving its size at 0 characters.
The standard defines empty()
like this:
bool empty() const noexcept;
Returns: size() == 0.
You'd be hard-pressed to find something that doesn't do that, and any performance difference would be negligible due to both being constant time operations. I would expect both to compile to the exact same assembly on any reasonable implementation.
That said, empty()
is clear and explicit. You should prefer it over size() == 0
(or !size()
) for readability.
Now, this is a pretty trivial matter, but I'll try to cover it exhaustively so whatever arguments are put by colleagues aren't likely to take you by surprise....
As usual, if profiling proved you really really had to care, measure: there could be a difference (see below). But in a general code review situation for not-proved-problematically-slow code, the outstanding issues are:
in some other containers (e.g. C++03 lists but not C++11), size()
was less efficient than empty()
, leading to some coding tips to prefer empty()
over size()
in general so that if someone needed to switch the container later (or generalise the processing into a template where the container type may vary) no change needs to be made to retain efficiency.
does either reflect a more natural way to conceive of the test? - not just what you happened to think of first, or size()
because you're not as used to using empty()
, but when you're 100% focused on the surrounding code logic, does size()
or empty()
fit in better? For example, perhaps because it's one of several tests of size()
and you like having consistency, or because you're implementing a famous algorithm or formula that's traditionally expressed in terms of size: being consistent might reduce the mental noise/effort in verifying the implementation against the formula.
Most of the time the factors above are insignificant, and raising the issue in a code review is really a waste of time.
Possible performance difference
While the Standard requires functional equivalence, some implementations might implement them differently, though I've struggled and so far failed to document a particularly plausible reason for doing so.
C++11 has more constraints than C++03 over behaviours of other functions that impact implementation choices: data()
must be NUL terminated (used to be just c_str()
), [size()]
is now a valid index and must return a reference to a NUL character. For various subtle reasons, these restrictions make it even more likely that empty()
will be no faster than size()
.
Anyway - measure if you have to care.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With