At present, time complexity of size()
for all STL containers is underspecified. There's an open C++ defect report for that.
The present ISO C++ standard says that STL containers should have size()
of constant complexity:
21.3[lib.basic.string]/2
The class template basic_string conforms to the requirements of a Sequence, as specified in (23.1.1). Additionally, because the iterators supported by basic_string are random access iterators (24.1.5), basic_string conforms to the the requirements of a Reversible Container, as specified in (23.1).
23.1[lib.container.requirements]/5
- Expression:
a.size()
- Complexity: (Note A)
Those entries marked ‘‘(Note A)’’ should have constant complexity
However, "should" is not a binding requirement in the Standard parlance; indeed, the above applies to std::list
as well, but in practice some implementations (notably g++) have O(N) std::list::size()
.
The only thing that can be guaranteed is that (end() - begin())
for a string is (possibly amortized) O(1). This is because string iterators are guaranteed to be random-access, and random-access iterators are guaranteed to have constant time operator-
.
As a more practical issue, for all existing C++ implementations out there, the following holds:
std::string::size()
is O(1)
std::vector::size()
is O(1)
They are fairly obvious, as both strings and vectors are most efficiently implemented as contiguous arrays with separately stored size: contiguous because it gives fastest element access while satisfying all other complexity requirements, and storing size is because Container requirements demand that end()
be constant-time.