Opened 5 years ago

Last modified 5 years ago

#13140 new Bugs

Quadratic complexity of a flat_set constructor

Reported by: victor.zverovich@… Owned by: Ion Gaztañaga
Milestone: To Be Determined Component: container
Version: Boost 1.63.0 Severity: Problem
Keywords: Cc:

Description

The documentation of boost flat_set constructor taking two iterators says:

template<typename InputIterator> 
  flat_map(InputIterator first, InputIterator last, 
           const Compare & comp = Compare(), 
           const allocator_type & a = allocator_type());

Effects: Constructs an empty flat_map using the specified comparison object and allocator, and inserts elements from the range [first ,last ).

Complexity: Linear in N if the range [first ,last ) is already sorted using comp and otherwise N logN, where N is last - first.

However, the complexity of this constructor is O(N*N) because the implementation of the constructor inserts each element into a vector at position found by binary search and insertion is linear in distance to the end of the vector.

A simple fix is to insert all elements at once and sort the vector backing flat_set.

Change History (4)

comment:1 by anonymous, 5 years ago

I mixed flat_map and flat_set above but the same issue applies to both.

comment:2 by John Maddock, 5 years ago

Component: Nonecontainer
Owner: set to Ion Gaztañaga

comment:3 by Constantin Makshin <cmakshin@…>, 5 years ago

The suggested fix will create invalid map/set if the source range contains values which must be "collapsed" into one element of the target container (pairs with the same first element for map, same values for set).

comment:4 by victor.zverovich@…, 5 years ago

This can be fixed by additional unique pass without changing the complexity (also the sort might have to be stable in this case).

Note: See TracTickets for help on using tickets.