Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is list::size() really O(n)?

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

  1. So my guess is that for the VC++ crowd size() has constant complexity as Dinkumware probably won't have changed that fact since VC6. Am I right there?
  2. What does it look like currently in gcc? If it is really O(n), why did the developers choose to do so?
like image 341
foraidt Avatar asked Oct 23 '08 08:10

foraidt


People also ask

Is list size () O 1 or O N?

size() is O(1). While other answers have correctly said that implementations such as ArrayList and LinkedList explicitly store the lists size as a field of the list, that doesn't actually answer your question, because List. of​(E... elements) doesn't use those implementations.

How do you give a list a size in C++?

list::size() is an inbuilt function in C++ STL which is declared in <list> header file. size() returns the size of a particular list container. In other words it returns the number of elements which are present in a list container.

Should I use std :: list?

From a performance standpoint, the best reason to use std::list is so that when later on your app is suffering badly for performance and needs "an optimziation pass", you can replace it with another data structure and look like a hero.


1 Answers

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();} 
like image 183
kennytm Avatar answered Oct 05 '22 13:10

kennytm