Recently, I noticed some people mentioning that std::list::size()
has a linear complexity.
According to some sources, this is in fact implementation dependent as the standard doesn't say what the complexity has to be.
The comment in this blog entry says:
Actually, it depends on which STL you are using. Microsoft Visual Studio V6 implements size() as {return (_Size); } whereas gcc (at least in versions 3.3.2 and 4.1.0) do it as { return std::distance(begin(), end()); } The first has constant speed, the second has o(N) speed
size()
has constant complexity as Dinkumware
probably won't have changed that fact since VC6. Am I right there?gcc
? If it is really O(n), why did the
developers choose to do so?In C++11 it is required that for any standard container the .size()
operation must be complete in "constant" complexity (O(1)). (Table 96 — Container requirements). Previously in C++03 .size()
should have constant complexity, but is not required (see Is std::string size() a O(1) operation?).
The change in standard is introduced by n2923: Specifying the complexity of size() (Revision 1).
However, the implementation of .size()
in libstdc++ still uses an O(N) algorithm in gcc up to 4.8:
/** Returns the number of elements in the %list. */
size_type
size() const _GLIBCXX_NOEXCEPT
{ return std::distance(begin(), end()); }
See also Why is std::list bigger on c++11? for detail why it is kept this way.
Update: std::list::size()
is properly O(1) when using gcc 5.0 in C++11 mode (or above).
By the way, the .size()
in libc++ is correctly O(1):
_LIBCPP_INLINE_VISIBILITY
size_type size() const _NOEXCEPT {return base::__sz();}
...
__compressed_pair<size_type, __node_allocator> __size_alloc_;
_LIBCPP_INLINE_VISIBILITY
const size_type& __sz() const _NOEXCEPT
{return __size_alloc_.first();}