IntQueue
This commit is contained in:
parent
a3c111b5f5
commit
c6c6fffac9
111
src/main/java/com/dataStructures/IntQueue.java
Normal file
111
src/main/java/com/dataStructures/IntQueue.java
Normal file
@ -0,0 +1,111 @@
|
||||
package com.dataStructures;
|
||||
|
||||
/**
|
||||
* This file contains an implementation of an integer only queue which is extremely quick and
|
||||
* lightweight. In terms of performance it can outperform java.util.ArrayDeque (Java's fastest queue
|
||||
* implementation) by a factor of 40+! See the benchmark test below for proof. However, the downside
|
||||
* is you need to know an upper bound on the number of elements that will be inside the queue at any
|
||||
* given time for this queue to work.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
public class IntQueue {
|
||||
|
||||
private int[] ar;
|
||||
private int front, end, sz;
|
||||
|
||||
// maxSize is the maximum number of items
|
||||
// that can be in the queue at any given time
|
||||
public IntQueue(int maxSize) {
|
||||
front = end = 0;
|
||||
sz = maxSize + 1;
|
||||
ar = new int[sz];
|
||||
}
|
||||
|
||||
// Return true/false on whether the queue is empty
|
||||
public boolean isEmpty() {
|
||||
return front == end;
|
||||
}
|
||||
|
||||
// Return the number of elements inside the queue
|
||||
public int size() {
|
||||
if (front > end) return (end + sz - front);
|
||||
return end - front;
|
||||
}
|
||||
|
||||
public int peek() {
|
||||
return ar[front];
|
||||
}
|
||||
|
||||
// Add an element to the queue
|
||||
public void enqueue(int value) {
|
||||
ar[end] = value;
|
||||
if (++end == sz) end = 0;
|
||||
if (end == front) throw new RuntimeException("Queue too small!");
|
||||
}
|
||||
|
||||
// Make sure you check is the queue is not empty before calling dequeue!
|
||||
public int dequeue() {
|
||||
int ret_val = ar[front];
|
||||
if (++front == sz) front = 0;
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
// Example usage to check the how fast this implementation is
|
||||
public static void main(String[] args) {
|
||||
|
||||
IntQueue q = new IntQueue(5);
|
||||
|
||||
q.enqueue(1);
|
||||
q.enqueue(2);
|
||||
q.enqueue(3);
|
||||
q.enqueue(4);
|
||||
q.enqueue(5);
|
||||
|
||||
System.out.println(q.dequeue()); // 1
|
||||
System.out.println(q.dequeue()); // 2
|
||||
System.out.println(q.dequeue()); // 3
|
||||
System.out.println(q.dequeue()); // 4
|
||||
|
||||
System.out.println(q.isEmpty()); // false
|
||||
|
||||
q.enqueue(1);
|
||||
q.enqueue(2);
|
||||
q.enqueue(3);
|
||||
|
||||
System.out.println(q.dequeue()); // 5
|
||||
System.out.println(q.dequeue()); // 1
|
||||
System.out.println(q.dequeue()); // 2
|
||||
System.out.println(q.dequeue()); // 3
|
||||
|
||||
System.out.println(q.isEmpty()); // true
|
||||
|
||||
benchMarkTest();
|
||||
}
|
||||
|
||||
// BenchMark IntQueue vs ArrayDeque.
|
||||
private static void benchMarkTest() {
|
||||
|
||||
int n = 10000000;
|
||||
IntQueue intQ = new IntQueue(n);
|
||||
|
||||
// IntQueue times at around 0.0324 seconds
|
||||
long start = System.nanoTime();
|
||||
for (int i = 0; i < n; i++) intQ.enqueue(i);
|
||||
for (int i = 0; i < n; i++) intQ.dequeue();
|
||||
long end = System.nanoTime();
|
||||
System.out.println("IntQueue Time: " + (end - start) / 1e9);
|
||||
|
||||
// ArrayDeque times at around 1.438 seconds
|
||||
java.util.ArrayDeque<Integer> arrayDeque = new java.util.ArrayDeque<>();
|
||||
// java.util.ArrayDeque <Integer> arrayDeque = new java.util.ArrayDeque<>(n); // strangely the
|
||||
// ArrayQueue is slower when you give it an initial capacity.
|
||||
start = System.nanoTime();
|
||||
for (int i = 0; i < n; i++) arrayDeque.offer(i);
|
||||
for (int i = 0; i < n; i++) arrayDeque.poll();
|
||||
end = System.nanoTime();
|
||||
System.out.println("ArrayDeque Time: " + (end - start) / 1e9);
|
||||
}
|
||||
}
|
128
src/test/java/com/dataStructures/IntQueueTest.java
Normal file
128
src/test/java/com/dataStructures/IntQueueTest.java
Normal file
@ -0,0 +1,128 @@
|
||||
package com.dataStructures;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.util.*;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
public class IntQueueTest {
|
||||
|
||||
@Before
|
||||
public void setup() {}
|
||||
|
||||
@Test
|
||||
public void testEmptyQueue() {
|
||||
IntQueue queue = new IntQueue(0);
|
||||
assertTrue(queue.isEmpty());
|
||||
assertEquals(queue.size(), 0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Test
|
||||
public void testEnqueueOneElement() {
|
||||
IntQueue queue = new IntQueue(1);
|
||||
queue.enqueue(77);
|
||||
assertEquals(queue.size(), 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAll() {
|
||||
int n = 5;
|
||||
IntQueue queue = new IntQueue(10);
|
||||
assertTrue(queue.isEmpty());
|
||||
for (int i = 1; i <= n; i++) {
|
||||
queue.enqueue(i);
|
||||
assertFalse(queue.isEmpty());
|
||||
}
|
||||
for (int i = 1; i <= n; i++) {
|
||||
assertEquals(i, queue.peek());
|
||||
assertEquals(i, queue.dequeue());
|
||||
assertEquals(queue.size(), n - i);
|
||||
}
|
||||
assertTrue(queue.isEmpty());
|
||||
n = 8;
|
||||
for (int i = 1; i <= n; i++) {
|
||||
queue.enqueue(i);
|
||||
assertFalse(queue.isEmpty());
|
||||
}
|
||||
for (int i = 1; i <= n; i++) {
|
||||
assertEquals(i, queue.peek());
|
||||
assertEquals(i, queue.dequeue());
|
||||
assertEquals(queue.size(), n - i);
|
||||
}
|
||||
assertTrue(queue.isEmpty());
|
||||
n = 9;
|
||||
for (int i = 1; i <= n; i++) {
|
||||
queue.enqueue(i);
|
||||
assertFalse(queue.isEmpty());
|
||||
}
|
||||
for (int i = 1; i <= n; i++) {
|
||||
assertEquals(i, queue.peek());
|
||||
assertEquals(i, queue.dequeue());
|
||||
assertEquals(queue.size(), n - i);
|
||||
}
|
||||
assertTrue(queue.isEmpty());
|
||||
n = 10;
|
||||
for (int i = 1; i <= n; i++) {
|
||||
queue.enqueue(i);
|
||||
assertFalse(queue.isEmpty());
|
||||
}
|
||||
for (int i = 1; i <= n; i++) {
|
||||
assertEquals(i, queue.peek());
|
||||
assertEquals(i, queue.dequeue());
|
||||
assertEquals(queue.size(), n - i);
|
||||
}
|
||||
assertTrue(queue.isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPeekOneElement() {
|
||||
IntQueue queue = new IntQueue(1);
|
||||
queue.enqueue(77);
|
||||
assertTrue(queue.peek() == 77);
|
||||
assertEquals(queue.size(), 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDequeueOneElement() {
|
||||
IntQueue queue = new IntQueue(1);
|
||||
queue.enqueue(77);
|
||||
assertTrue(queue.dequeue() == 77);
|
||||
assertEquals(queue.size(), 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRandom() {
|
||||
|
||||
for (int qSize = 1; qSize <= 50; qSize++) {
|
||||
|
||||
IntQueue intQ = new IntQueue(qSize);
|
||||
ArrayDeque<Integer> javaQ = new ArrayDeque<>(qSize);
|
||||
|
||||
assertEquals(javaQ.isEmpty(), intQ.isEmpty());
|
||||
assertEquals(javaQ.size(), intQ.size());
|
||||
|
||||
for (int operations = 0; operations < 5000; operations++) {
|
||||
|
||||
double r = Math.random();
|
||||
|
||||
if (r < 0.60) {
|
||||
int elem = (int) (1000 * Math.random());
|
||||
if (javaQ.size() < qSize) {
|
||||
javaQ.offer(elem);
|
||||
intQ.enqueue(elem);
|
||||
}
|
||||
} else {
|
||||
if (!javaQ.isEmpty()) {
|
||||
assertEquals((int) javaQ.poll(), (int) intQ.dequeue());
|
||||
}
|
||||
}
|
||||
|
||||
assertEquals(javaQ.isEmpty(), intQ.isEmpty());
|
||||
assertEquals(javaQ.size(), intQ.size());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user