Fastest list/vector/queue ?

Started by
20 comments, last by Fruny 18 years, 10 months ago
Quote:Original post by crucifer

nprz
Quote:reading values at random locations: meaning you have an index number? list will be slow at this because you need to iterate through it. vector and deque are O(1).


Hmmm ... that's very interesting ... how can deque be O(1) for random read ?


The way it is stored is very interesting :) It stores the data like a vector but in blocks. It can determine which block you want from the index, and after dereferencing the block, it can get you to the value, all in constant time.

It is a bit more bulky than vector, but if you are doing inserts near the front, it is better than a vector. Resizes also take like time because it just shuffles pointers and allocates more memory rather than copying all the individual data.
Advertisement
Quote:Original post by crucifer
I am currently coding in C++ and I need some storage solution (list/vector/queue ... etc) that can do :

-inserts values at random locations
-read values at random locations
-pop of the first or last values


Preferably, if I could do any of these operations in O(1), I would be glad.

Anybody has a guess ?


You want a deque. You are incorrect is calling it a "list that's bidirectional", list is a linked list that is bidirectional ("doubly linked" is the more common term). slist, which isn't standard, is a single direction list ("singly linked" is the more common term). deque is a "double ended queue". It's usually pronounced "deck" and that's how you should think of it, like a deck of cards. Each card is an array of elements. If you want to insert at a random location, you pick the card with the location you need and add the element to that array. If that card is full, you just insert another card. If you want to read values at random locations, you go to the card with that location and read it. Popping a first or last value is easy, just move the "begin" pointer one element forward (pop_front) or the "end" pointer one element back (pop_back). It's designed to do what you want. Granted, not O(1), but I believe it's amortized behavior is O(1).

So, why vector and list? Because they have smaller constants. Where the constant dominates, or where you have only need of one of those behaviors, they will outperform deque.

By the way, are you sure it'll make a difference? Most people asking about such things are using such small collections that it won't make a noticeable difference.
Well....


thanks a lot "nprz" and "Anonymous Poster" ...

I guess deque is indeed the perfect solution to my problem.

Thx guys.
Quote:Original post by crucifer
I was looking for some type of storage or maybe some type of combination of storages that could give me the best performance for ALL the operations.


Best for ALL operations? Most programmers don't come up with new data structures just for kicks. If there were a best for ALL operations, programmers would only use that.

Quote:
BUT ... in case no one has a better idea, here is an approximate ratio of the type of operations I can do on my storage (wich can contain up to ~10,000 values)

-reads = 90% of the operations (binary search)
-insert = 3%
-pop front = 7%


You can't do a binary search on lists, so performance there will be horrid.

10,000 isn't necessarily a lot, depending on how large the data type is. Have you profiled and found this to be a bottle neck?

Quote:
keep in mind that even if the 3% is very small, moving 10,000 values in the ram is very long ... and thus, the vector is probably the worst solution.


Have you profiled that?

Quote:
In 1st position, I'm guessing that the list would be the champion ?


Switching containers is relatively painless, why not profile them? That's the only SURE way of knowing.
How about a map?

Random access is relatively fast, and the "binary search" is built-in.
Insertion and removal is relatively fast, too.
John BoltonLocomotive Games (THQ)Current Project: Destroy All Humans (Wii). IN STORES NOW!
Quote:Original post by DerAnged
You definately want a list in this situation, linked or std::
std::list is a doubly-linked list and std::slist is a singly-linked list, so I'm not sure what you mean by this.
Quote:Original post by crucifer
I was looking for some type of storage or maybe some type of combination of storages that could give me the best performance for ALL the operations.

BUT ... in case no one has a better idea, here is an approximate ratio of the type of operations I can do on my storage (wich can contain up to ~10,000 values)

-reads = 90% of the operations (binary search)
-insert = 3%
-pop front = 7%

keep in mind that even if the 3% is very small, moving 10,000 values in the ram is very long ... and thus, the vector is probably the worst solution.

In 1st position, I'm guessing that the list would be the champion ?


Really? i'd be surprised that moving 10K takes more then a ms. (the transfer rates for ram's nowerdays are in the 100's of mb/s)

denc

Click here to patch the mozilla IDN exploit, or click Here then type in Network.enableidn and set its value to false. Restart the browser for the patches to work.
Quote:Original post by JohnBolton
How about a map?

Random access is relatively fast, and the "binary search" is built-in.
Insertion and removal is relatively fast, too.


It all depends on what he is using the data structure for (which he hasn't really said). A map wouldn't be an option if you didn't want it sorted.
Linked lists are O(x) (x being the index used) while vectors (I believe) are O(1), when it comes to random access. Popping is O(1) for both (assuming the linked list has pointers to the beginning and the end, not sure if std::list has this or not [might depend on the implementation]). Also you asked how deque lookups could be O(1): the deque internally uses an array, and when you do array on an array, it means *(array + i), which is O(1) since it's reading from a known location from the RAM.
Quote:Original post by nprz
Quote:Original post by JohnBolton
How about a map?

Random access is relatively fast, and the "binary search" is built-in.
Insertion and removal is relatively fast, too.


It all depends on what he is using the data structure for (which he hasn't really said). A map wouldn't be an option if you didn't want it sorted.


Sorting it has nothing to do with it. If you're using integers, then using a map still won't put key 10 before key 9. However, I'm not sure if a map with integer keys can beat vector/deque. If keys are unimportant and sorting is unimportant, set may be better. If you don't want keys, but you want order, vector/list/deque are probably your best bets, but map may surprise you. Keyword: profile.

This topic is closed to new replies.

Advertisement