Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Queue performance wise which is better implementation - Array or Linked list

Which way gives the faster enqueueing and dequeuing when I have to insert very few elements, Is array better than a linked list?

I need to insert few element and I have to remove and read that removed element from queue. If it is array I may have to modify the indexes every time I remove an element. Inserting and deleting may happen simultaneously also.

Which one is better from below case?

typedef struct{
    mylist list;
    struct mylistQ *next;
}mylistQ;

Array Code

 static mylist myListQ[QUEUESIZE+1];
int qLast = 0;

void enqueue_element(mylist qItem)
{
        myListQ[qLast] = qItem;
    qLast++;
}

mylist dequeue_element()
{
 retryq:
   if(qLast >0) {
    mylist qReturn = myListQ[0];  
    int i;
    for (i = 0; i < qLast - 1; i++){
        myListQ[i] = myListQ[i + 1];
    }
    qLast--; 
    return qReturn;
     }
   else {
    goto retryq;
    }
}

Linked List

 int qLast = 0;

mylistQ *headElement = NULL;   
mylistQ *tailElement = NULL;     

void enqueue_element(mylist *List)
{
    mylistQ *newnode;      
    newnode=(mylistQ*)av_malloc(sizeof(mylistQ));
    newnode->next=NULL;
    newnode->list=*List;
    qLast++;
    if(headElement==NULL && tailElement==NULL)
    {
        headElement=newnode;
        tailElement=newnode;
    }
    else
    {
        tailElement->next=newnode;
        tailElement=newnode;
    }
 }

mylist dequeue_element()
{
    mylistQ *delnode;      /* Node to be deleted */
    mylist Dellist;
    if(headElement==NULL && tailElement==NULL){
        LOg( "Queue is empty to delete any element");
        }
    else
    {
       Log("In dequeue_picture queue is not empty");
        delnode=headElement;
        headElement=headElement->next;
    if (!headElement){
        tailElement=NULL;
    }
        Dellist = delnode->list;
        av_free(delnode);
    qLast--;
    }
        return Dellist;
}
like image 490
Anil Arrabole Avatar asked Feb 24 '11 22:02

Anil Arrabole


People also ask

Is it better to implement a queue as an array or a linked list?

The linked list versions have better worst-case behavior, but may have a worse overall runtime because of the number of allocations performed. The array versions are slower in the worst-case, but have better overall performance if the time per operation isn't too important.

What is the advantage of implementing a queue using a linked list over an array?

Queue supports operations like enqueue and dequeue. It can be implemented using an array and linked list. The benefit of implementing a queue using a linked list over arrays is that it allows to grow the queue as per the requirements, i.e., memory can be allocated dynamically.

Which is faster linked list or array?

Linked list have slower search times than arrays as random access is not allowed. Unlike arrays where the elements can be search by index, linked list require iteration.

Why might we prefer to implement a queue with a linked list instead of an array?

The operation of removing the first item from a linked list runs at O(1) or constant time, whereas an array would run at O(n), n being dependent upon the array's length. So this concludes why you would use a Linked List instead of an Array.


1 Answers

It depends on how many operations you'll be performing and exactly how the array version is implemented.

If you're doing comparatively few operations, ie less than 1000 or so enqueue/dequeues in total, then an array would be faster because it is contiguous in memory. Maintain a pointer to the front and a pointer to the back, always add at the back and dequeue at the front.

On the other hand even if the list is no longer than 30 or so elems ever, if this has to persist of a long period you won't have any array resizing issues which is a potential problem with the array.

Linked list is guaranteed excellent performance, array you have to watch for resizing.

EDIT: As mentioned by @Hans Passant, arrays are fast because they have CPU cache locality. As long as your array is small, your hardware will optimize performance such that the memory associated with storing the array will be kept in your L2. Indices likely in registers. This is REALLY fast. Judging by the fact that you won't need many elements, an array would be ideal in this case. And yes, you will have to modify indices when you move elements, but this is actually an extremely fast operation since if you build the code with optimization the indices will be stored in registrars.

Here's the catch though, you mention you may have to do both enqueue and dequeue at the same time, by this do you mean it's parallel ie multiple threads accessing the memory? If this is the case, arrays would still be faster, but you'll see something like a 800 fold decrease in performance. Why? because no longer can the processor buffer the memory associated with your queue on the die, but it must be stored in main memory. In addition, you're running the risk of creating a race condition between threads. Imagine if one thread tried to dequeue while another tried to enqueue and there was only one elem in the list, you could have disaster. Either way, if this application is very perfromance driven, be sure to compile (assuming gcc) with the NDEBUG and -O3 flags on.

Second Edit: Looking at the code, and looking below at other answers, I'd suggest making your array code more efficient and turning it into a circular array since it sounds like you have an upper bound on the number of elements. As a side note, you're current array implementation is extremely inefficient, every time you remove you copy forward the rest of the Queue, this makes no sense, just increment a int pointer to the "first" index.

Pseudo Code:

int ciruclarArray[SIZE];
int front = 0;
int back = 0;

void enqueue(int elem)
{
    circularArray[back] = elem;
    if(back < (circularArray.length - 1))
        back++;
    else
        back = 0;
    return elem;
}

int dequeue()
{
    int toReturn = circularArray[front];
    //do same check for incrementing as enqueue
    return toReturn;
}

just don't forget to do error checking for the normal stuff.

like image 71
themaestro Avatar answered Sep 24 '22 07:09

themaestro