Eqbal
Eqbal

Reputation: 4880

A fast queue in Java

I am looking for a fast queue implementation in Java. I see that LinkedList implements the Queue interface, but it will only be as fast as a LinkedList right? Is there a way to have a queue that will be faster especially for add (I only need poll, add and check for empty). Down the line I may also need a PriorityQueue but not yet.

Upvotes: 26

Views: 35592

Answers (5)

Thomas Mauch
Thomas Mauch

Reputation: 91

You may want to have a look at https://dzone.com/articles/gaplist-lightning-fast-list which introduces GapList. This new list implementation combines the strengths of both ArrayList and LinkedList.

It therefore implements the Deque interface, but can also be presized like the above mentioned ArrayDeque. In addition, you also get all the possibilities of the List interface for free. Get it at https://github.com/magicwerk/brownies-collections.

Upvotes: 4

Jan Cajthaml
Jan Cajthaml

Reputation: 403

Start with really simplistic rotating Queue implementation with "C/C++ like" attitude and fixed size.

class SimpleQueue<E>
{

int index   = 0;
int head    = 0;
int size    = 100;
int counter = 0;
E[] data    ;


@SuppressWarnings("unchecked")
SimpleQueue()
{
    data = (E[]) new Object[size];
}

public void add(E e)
{
    data[index]=e;
    index=(index+1)%size;
    counter++;
}

public E poll()
{
    E value = data[head];
    head=(head+1)%size;
    counter--;
    return value;
}

public boolean empty()
{ return counter==0; }

//Test
public static void main(String[] args)
{
    SimpleQueue<Integer> s = new SimpleQueue<Integer>();

    System.out.println(s.empty());

    for(int i=0; i< 10; i++)
        s.add(i);

    System.out.println(s.empty());

    for(int i=0; i<10; i++)
        System.out.print(s.poll()+",");

    System.out.println("\n"+s.empty());

}
}

And then improve it.

Upvotes: 1

Jay
Jay

Reputation: 27464

If performance of a linked list was really a problem, an alternative would be to implement a "circular queue" in an array, i.e. a queue where the start and end point move as entries are added and deleted. I can give more details if you care. When I was using languages that did not have a library of collections, this was how I always implemented queues because it was easier to write than a linked list and it was faster. But with built-in collections, the effort of writing and debugging my own collection for a special case is not worth the trouble 99% of the time: When it's already written, the fact that I could write it a different way faster than I could re-write it the way Java does is pretty much an irrelevant fact. And any performance gain is likely to be too small to be worth the trouble. I sub-type existing collections to get special behavior I need now and then, but I'm hard-pressed to think of the last time that I wrote one from scratch.

Upvotes: 6

Noel Ang
Noel Ang

Reputation: 5099

I see that LinkedList implements the Queue interface, but it will only be as fast as a LinkedList right?

Eyeballing the source code, LinkedList is O(1) for Queue.add, Queue.poll, and Queue.peek operations.

I hope that's fast enough.

Upvotes: 31

Adamski
Adamski

Reputation: 54697

If multiple threads are going to be accessing the queue then consider using an ArrayBlockingQueue. Otherwise take a look at ArrayDeque. From the ArrayDeque API:

This class is likely to be faster than Stack when used as a stack, and faster than LinkedList when used as a queue.

Specifically an array-based queue implementation reduces the need to resize the underlying array if the existing array has sufficient capacity, thus making additions to the queue generally faster than LinkedList. Be aware that ArrayBlockingQueue is a bounded implementation whereas ArrayDeque will resize as required.

The flip-side is that LinkedList will typically provide a much more compact representation, particularly in cases where your queue grows and shrinks by a large amount. For example, if you added 10,000,000 elements to an ArrayDeque and then removed 9,999,999 elements, the underlying array would still be of length 10,000,000 whereas a LinkedList would not suffer from this problem.

In reality, for single-threaded access to a non-blocking queue I tend to favour LinkedList. I imagine the performance differences are so negligable you wouldn't notice the difference anyway.

Upvotes: 35

Related Questions