views:

121

answers:

2

I'm writing a lighter version of some containers from STL for myself.

(I know that STL was written by professional programmers and I am too stupid or too ambitious if think that I can write it better than they did. When I wrote my list (only with method I need), it worked few times faster. So, I thought it's a good idea. But, anyway.)

I was disappointed by speed of std::stack::pop(). I glanced at souses and found that there's no great algorithm. Nearly as I did, I suppose:

void pop()
{
  if(topE) // topE - top Element pointer
  {
     Element* n_t = topE->lower; // element 'under' that one
     delete topE;
     topE = n_t;
  }
}

But it works much slower than STL's one.

erase(--end());

Can anybody explain me why iterator erase is faster?

+3  A: 

It's a bit hard to say much about the performance of the standard library stack, because it's a container adapter, not a container in itself. All the operations get passed through to the underlying container with (at most) minor modifications.

There are a couple of obvious possibilities though. First of all, you're apparently using a linked list; by default, std::stack will use a vector, at least if memory serves. Second, it's just erasing the item, which destroys the object, but does not release the underlying memory. Yours appears to destroy the object and delete the memory.

Jerry Coffin
Actually `std::stack` uses a deque by default.
Fred Larson
+6  A: 

Because of delete topE.

With STL (at least for the SGI implementation), there is no automatic delete on pop(). If you've dynamically allocated the elements in the stack, it's up to you to deallocate before calling pop().

The STL pop just shortens the stack size by one (and destroys the last object - not necessarily a heap delete).

The next thing is that (it looks like) you're using a linked list to store the stack. That's going to be wayyyy slower than the default STL container (SGI uses deque) because you'll lose cache locality and require dynamic allocation for each element (new/delete) - whereas a deque will dynamically allocate chunks of the stack at a time.

You said it best:

STL was written by professional programmers and I am too stupid or too ambitious if think that I can write it better than they did

At least for now :) Try and see how close you get!

Stephen
@Charles: The destructor of the object there is called. `delete` is not called because the objects aren't stored as pointers in STL containers.
Billy ONeal
@Charles Bailey - if you're storing pointers, it won't be deleted. Destroy will call the destructor of the object - not necessarily a heap delete. Did my edit make that any more clear?
Stephen
I haven't caught few things:1. What is the difference between 'delete by pointer'(from heap) and destroy object?2. I've been trying to find out how deque works, but found only one forum thread: http://cboard.cprogramming.com/cplusplus-programming/78898-how-do-deques-work.html in which people says that deque is a linked list. Strange.
MInner
@MInner, both of those topics could be a question in themselves :) Regarding the containers: A vector is implemented with a dynamic array that will be copied when it needs to grow. It sounds slow, but in practice it's faster than lots of small allocations. A deque improves on the vector by storing a linked_list of small arrays. So, you get the benefit of a contiguous memory chunk, but can grow your array (in both the front and the back) with smaller chunks.
Stephen
@MInner, Regarding delete vs destroy. It's essentially the difference between destruction of a delete allocated variable and a stack allocated variable. The destructor will be called, but it doesn't involve the heap (which is generally going to be a slower operation). Imagine this with 'int': you can `int *p = new int;` then `delete p;`, but destroying an `int` does nothing - very cheap!
Stephen
Hah. I thought that vector works the way you told deque works :) (It more logical than coping and coping). Thank you a lot. Now I caught it, I suppose.
MInner