6

The std::queue class is unclear as to the complexity of the size member function. It appears to be based on the data structure implementation used at the time.

One would assume that size would be O(C), but it's totally possible for it to be O(N). Obviously, I can keep my own size, but I would rather just call size.

(Question modified): since deque is the default container, what is O ( ) of std::deque::size()?

Mark Gerolimatos
  • 2,424
  • 1
  • 23
  • 33

5 Answers5

9

At least since C++11, the complexity of std::queue::size is constant: O(1).

This is guaranteed by the fact that the underlying container of std::queue, as per §23.6.3.1/1, have to fit the requirements of SequenceContainer, that inherits the requirement of Container, which, in turn, as per §23.2.1, requires the member function size to have a constant time complexity.

Shoe
  • 74,840
  • 36
  • 166
  • 272
3

To sum up the very good answers here:

  • C++11: O(1) (@Jeffrey)
  • C++98: unenforced, need to do experimentation based on the container class
  • C++98 with default container: the default container for std::queue is std::deque, which calculates size by subtracting two iterators, which is not O(1), but at least O(C). (@juanchopanza)

Thus, if you need to ensure O(1)-ness of size() in C++98, you must keep your own count.

If I might, I would like to step on my soap box and thank the C++11 group for closing this horrendous specification hole. Many languages/libraries (such as Scala) take great pains to define the BIG-O of an operator. Given that the main use case of C++ is performance, I find this lack of specification amazing. It is completely unacceptable that one should have to inspect header code to determine performance characteristics of std classes.

Mark Gerolimatos
  • 2,424
  • 1
  • 23
  • 33
1

std::queue::size is specified exactly in C++11 23.6.3.1/1:

size_type size() const { return c.size(); }

where c is a protected data member whose type is that of the second template parameter. Ergo, its complexity is exactly that of the size member function of said template parameter. The default is std::deque<T> - where T is the first template parameter passed to std::queue - which has the default O(1) complexity requirement common to all containers unless otherwise specified (per Table 96 in 23.2.1).

Casey
  • 41,449
  • 7
  • 95
  • 125
0

The complexity is constant O(1).

Constant (calling size on the underlying container). http://www.cplusplus.com/reference/queue/queue/size/

0

It may depend on the implementation you use, and it's best to check this yourself. Hopefully inspecting header files are not that hard. Even though newer standards mandate that it should be constant, that's the only way to be sure. For one example worth noting, gcc's libstdc++ still has O(n) for std::list.

dragonroot
  • 5,653
  • 3
  • 38
  • 63
  • Wow. When it comes to libraries, especially the STD, "use the source Luke" is not a happy answer. However, glad to hear that in C++11 things are a bit more stringent. – Mark Gerolimatos Feb 11 '14 at 22:11
  • 3
    @MarkGerolimatos To clarify: whether `size()` in a default queue is constant time **is not** implementation dependent. The standard mandated the default container used to be `std::deque`, and `std::deque::size` is constrained to be constant time. – juanchopanza Feb 11 '14 at 22:14
  • Indeed it's not. However, to quote one DMV handbook loosely, 'the fact that drivers are not allowed to run over you doesn't really prevent them from doing so'. – dragonroot Feb 11 '14 at 22:19
  • On the other hand, who would want to use an implementation that is non-standards compliant on such a basic level? – juanchopanza Feb 11 '14 at 22:23
  • I believe C++03 never required this. And the question did not refer to either any specific standard or any specific implementation. So the only answer I could have provided in that case is that nuking from the orbit is the only way to be sure. – dragonroot Feb 11 '14 at 22:31
  • @juanchopanza lots of people. Pretty much anyone who uses GCC. It's not the only noncompliance in libstdc++. (their std::string still uses COW too) – jalf Feb 11 '14 at 23:36