Selaa lähdekoodia

Merge pull request #11 from gammazero/bitmath

Bitwise math for speed
Evan Huus 9 vuotta sitten
vanhempi
commit
f0262ae409
1 muutettua tiedostoa jossa 11 lisäystä ja 5 poistoa
  1. 11 5
      queue.go

+ 11 - 5
queue.go

@@ -7,6 +7,8 @@ The queue implemented here is as fast as it is for an additional reason: it is *
 */
 package queue
 
+// minQueueLen is smallest capacity that queue may have.
+// Must be power of 2 for bitwise modulus: x % n == x & (n - 1).
 const minQueueLen = 16
 
 // Queue represents a single instance of the queue data structure.
@@ -30,7 +32,7 @@ func (q *Queue) Length() int {
 // resizes the queue to fit exactly twice its current contents
 // this can result in shrinking if the queue is less than half-full
 func (q *Queue) resize() {
-	newBuf := make([]interface{}, q.count*2)
+	newBuf := make([]interface{}, q.count<<1)
 
 	if q.tail > q.head {
 		copy(newBuf, q.buf[q.head:q.tail])
@@ -51,7 +53,8 @@ func (q *Queue) Add(elem interface{}) {
 	}
 
 	q.buf[q.tail] = elem
-	q.tail = (q.tail + 1) % len(q.buf)
+	// bitwise modulus
+	q.tail = (q.tail + 1) & (len(q.buf) - 1)
 	q.count++
 }
 
@@ -76,7 +79,8 @@ func (q *Queue) Get(i int) interface{} {
 	if i < 0 || i >= q.count {
 		panic("queue: Get() called with index out of range")
 	}
-	return q.buf[(q.head+i)%len(q.buf)]
+	// bitwise modulus
+	return q.buf[(q.head+i)&(len(q.buf)-1)]
 }
 
 // Remove removes the element from the front of the queue. If you actually
@@ -86,9 +90,11 @@ func (q *Queue) Remove() {
 		panic("queue: Remove() called on empty queue")
 	}
 	q.buf[q.head] = nil
-	q.head = (q.head + 1) % len(q.buf)
+	// bitwise modulus
+	q.head = (q.head + 1) & (len(q.buf) - 1)
 	q.count--
-	if len(q.buf) > minQueueLen && q.count*4 == len(q.buf) {
+	// Resize down if buffer 1/4 full.
+	if len(q.buf) > minQueueLen && (q.count<<2) == len(q.buf) {
 		q.resize()
 	}
 }