Benchmark compressedPostingIterator

This will set a baseline for comparing future improvements against.

  BenchmarkCompressedPostingIterator/100_50-8              2000000               878 ns/op         450.86 MB/s
  BenchmarkCompressedPostingIterator/10000_100-8             20000             64572 ns/op         446.30 MB/s
  BenchmarkCompressedPostingIterator/10000_1000-8            20000             76463 ns/op         388.13 MB/s
  BenchmarkCompressedPostingIterator/10000_10000-8           20000             82682 ns/op         359.22 MB/s
  BenchmarkCompressedPostingIterator/100000_100-8             2000            885923 ns/op         292.45 MB/s
  BenchmarkCompressedPostingIterator/100000_1000-8            2000            922484 ns/op         290.39 MB/s
  BenchmarkCompressedPostingIterator/100000_10000-8           2000           1028873 ns/op         260.51 MB/s
  BenchmarkCompressedPostingIterator/100000_100000-8          2000           1095734 ns/op         244.62 MB/s

Change-Id: Ib243d8b0e9499f62ca1423e83b526ebaa77739e1
diff --git a/hititer_test.go b/hititer_test.go
index 519a05e..0c276c1 100644
--- a/hititer_test.go
+++ b/hititer_test.go
@@ -15,6 +15,8 @@
 package zoekt
 
 import (
+	"fmt"
+	"math/rand"
 	"reflect"
 	"sort"
 	"testing"
@@ -55,3 +57,55 @@
 	}
 	return nums
 }
+
+func BenchmarkCompressedPostingIterator(b *testing.B) {
+	cases := []struct{ size, limitSize int }{
+		{100, 50},
+		{10000, 100},
+		{10000, 1000},
+		{10000, 10000},
+		{100000, 100},
+		{100000, 1000},
+		{100000, 10000},
+		{100000, 100000},
+	}
+	for _, tt := range cases {
+		b.Run(fmt.Sprintf("%d_%d", tt.size, tt.limitSize), func(b *testing.B) {
+			benchmarkCompressedPostingIterator(b, tt.size, tt.limitSize)
+		})
+	}
+}
+
+func benchmarkCompressedPostingIterator(b *testing.B, size, limitsSize int) {
+	nums := genUints32(size)
+	limits := genUints32(limitsSize)
+
+	nums = sortedUnique(nums)
+	sort.Slice(limits, func(i, j int) bool { return limits[i] < limits[j] })
+
+	ng := stringToNGram("abc")
+	deltas := toDeltas(nums)
+
+	b.ResetTimer()
+
+	for n := 0; n < b.N; n++ {
+		it := newCompressedPostingIterator(deltas, ng)
+		for _, limit := range limits {
+			it.next(limit)
+			_ = it.first()
+		}
+		var s Stats
+		it.updateStats(&s)
+		b.SetBytes(s.IndexBytesLoaded)
+	}
+}
+
+func genUints32(size int) []uint32 {
+	// Deterministic for benchmarks
+	r := rand.New(rand.NewSource(int64(size)))
+	nums := make([]uint32, size)
+	for i := range nums {
+		nums[i] = r.Uint32()
+	}
+	return nums
+}