Thread: std::list question

  1. #16
    Registered User Micko's Avatar
    Join Date
    Nov 2003
    Posts
    715
    Quote Originally Posted by Daved
    If you are doing all your insertions at once in the beginning, and then searching afterwards, then a vector would probably be even better than a map/multimap/set/multiset. Fill the vector with all your data, then sort it, then use binary_search, lower_bound, and/or upper_bound to find what you are looking for. This will be even better than the map solutions because those keep the data sorted as you are inserting which is a bit slower than sorting it once at the end. In addition, the vector uses less memory overhead than the map solutions.

    Another option is the unordered_map/unordered_multimap that will be part of the next standard. You can find an implementation from boost if your library doesn't have one. They're basically hashed maps, which have even faster lookups than the regular map or binary_search.
    Well that depends on actual data. If your data are not in form key/value than maybe it's better to use set container. Here's one quick and dirty example:
    Code:
    #include <iostream>
    #include <set>
    
    using namespace std;
    
    int main ( ) 
    {
        set <int> iSet;
        for (int i = 0; i < 10; i++)
        {
            iSet.insert(rand()%100);
        } 
        set <int> :: iterator it;
        for (it = iSet.begin(); it != iSet.end(); ++it)
        {
            cout << *it << " ";
        } 
        return 0;
    }
    I don't think that vector container would be good solution. You insert elements (needs time), sort elements (needs time) and then search for one particular element (needs time). Using set, map or multimap data are automatically sorted when inserted into container. Search of such structure is logarithmic (since it's basically binary search tree "under the hood") because it involves binary search.
    Gotta love the "please fix this for me, but I'm not going to tell you which functions we're allowed to use" posts.
    It's like teaching people to walk by first breaking their legs - muppet teachers! - Salem

  2. #17
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    I don't think that vector container would be good solution. You insert elements (needs time), sort elements (needs time) and then search for one particular element (needs time). Using set, map or multimap data are automatically sorted when inserted into container. Search of such structure is logarithmic (since it's basically binary search tree "under the hood") because it involves binary search.
    Inserting an element to a vector takes amortized constant time, so a sequence of insertions takes linear time. Inserting an element to a set would be an O(log n) operation, so a sequence of insertions would be O(n log n), which is the same as the sort of the vector. A search of the sorted vector takes logarithmic time too.

    Nicolai Josuttis, in chpater 6, section 9 of The C++ Standard Library: A Tutorial and Reference notes:
    "The automatic sorting of associative containers does not mean that these containers perform better when sorting is needed. This is because an associative container sorts each time a new element gets inserted. An often faster way is to use a sequence container and to sort all elements after they are all inserted by using one of the several sort algorithms."

    He then goes on to compare using a set to using a vector in sorting unique strings. The results for his system were stated as:
    "When I tried both programs with about 150,000 strings on my system, the vector version was approximately 10% faster. Inserting a call of reserve() made the vector version 5% faster. Allowing duplicates (using a multiset instead of a set and calling copy() instead of unique_copy() respectively) changed things dramatically: The vector version was more than 40% faster! These measurements are not representative; however, they do show that it is often worth trying different ways of processing elements."
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #18
    Registered User Micko's Avatar
    Join Date
    Nov 2003
    Posts
    715
    Interesting reading, thanks laserlight. however i said that all this depends on actual data that is used. What applies to integers and string no necessarlly applies to to other types (user defined types). So decision of what container to use is based on data types and the way they're inserted (if they are inserted all at once or not). In his case I would recommend to try different containers and to choose what is best for him. Also it will be a valueable experience and opportunity to learn something new!
    Gotta love the "please fix this for me, but I'm not going to tell you which functions we're allowed to use" posts.
    It's like teaching people to walk by first breaking their legs - muppet teachers! - Salem

  4. #19
    Supermassive black hole cboard_member's Avatar
    Join Date
    Jul 2005
    Posts
    1,709
    I'll give the vector idea a try too Daved.
    @IfYouSaySo: I see. Those are redundant calculations if kept inside the loop. <-- Right?
    Good class architecture is not like a Swiss Army Knife; it should be more like a well balanced throwing knife.

    - Mike McShaffry

  5. #20
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    however i said that all this depends on actual data that is used. What applies to integers and string no necessarlly applies to to other types (user defined types). So decision of what container to use is based on data types and the way they're inserted (if they are inserted all at once or not). In his case I would recommend to try different containers and to choose what is best for him.
    Of course. In fact, Josuttis goes on to write that:
    "In practice, predicting which container type is the best is often difficult. The big advantage of the STL is that you can try different versions without much effort. The major work - implementing the different data structures and algorithms - is done. You have only to combine them in a way that is best for you."

    Those are redundant calculations if kept inside the loop.
    I suspect it might be optimised away by the compiler.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  6. #21
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    >> Well that depends on actual data.
    I'm not sure how the data would effect the issue much. Even the use of data that is expensive to copy would probably be better addressed by storing a shared_ptr or using a ptr_vector or similar rather than switching to a map/set.

    >> If your data are not in form key/value than maybe it's better to use set container.
    Obviously you choose between map and set, multimap and multiset, unordered_map and unordered_set, and unordered_multimap and unordered_multiset based on whether you have a key/value pair or just a value that is its own key. If you're saying that having a key/value or not should mean choosing a set over the vector solution, I disagree, as vectors can hold key/value pairs nearly as easily as maps, and of course can hold single objects just as well as sets.

    IMO, you choose the container based on the most algorithmically efficient solution available given your expected use cases. If you think it might be a bottleneck in your code, make sure you code it so that the solution can be changed with minimal effect to other code by wrapping the container in a class or by some other method. Then, test your code to verify that the container is a bottleneck and experiment with other solutions at that time.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Debugging question
    By o_0 in forum C Programming
    Replies: 9
    Last Post: 10-10-2004, 05:51 PM
  2. Question about pointers #2
    By maxhavoc in forum C++ Programming
    Replies: 28
    Last Post: 06-21-2004, 12:52 PM
  3. std::list question
    By void_main in forum C++ Programming
    Replies: 5
    Last Post: 11-10-2003, 01:21 PM
  4. Question...
    By TechWins in forum A Brief History of Cprogramming.com
    Replies: 16
    Last Post: 07-28-2003, 09:47 PM
  5. Question, question!
    By oskilian in forum A Brief History of Cprogramming.com
    Replies: 5
    Last Post: 12-24-2001, 01:47 AM