From 67e3dc4a089af02574b92005f2ab0ac5e21b92f7 Mon Sep 17 00:00:00 2001 From: Seebs Date: Mon, 26 Nov 2018 13:10:21 -0600 Subject: [PATCH 1/2] roaring: improve SliceAscending/SliceDescending tests Two changes: First, make SliceDescending set the entire slice, not all-but-one bits. Second, add tests that are "striped", so it's writing to 8 parts of the slice sequentially, rather than just going up or down the whole thing, because that gives us some cheap indication of cache-locality impact, which turns out to be possibly significant. --- roaring/roaring_test.go | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/roaring/roaring_test.go b/roaring/roaring_test.go index f5c016ea3..a55393f1b 100644 --- a/roaring/roaring_test.go +++ b/roaring/roaring_test.go @@ -1348,5 +1348,40 @@ func BenchmarkSliceDescending(b *testing.B) { for col := uint64(pilosa.ShardWidth); col > uint64(0); col-- { bm.Add(col) } + bm.Add(0) + } +} + +func BenchmarkSliceAscendingStriped(b *testing.B) { + for n := 0; n < b.N; n++ { + bm := roaring.NewFileBitmap() + l := uint64(pilosa.ShardWidth / 8) + for col := uint64(0); col < l; col++ { + bm.Add(l*0 + col) + bm.Add(l*1 + col) + bm.Add(l*2 + col) + bm.Add(l*3 + col) + bm.Add(l*4 + col) + bm.Add(l*5 + col) + bm.Add(l*6 + col) + bm.Add(l*7 + col) + } + } +} + +func BenchmarkSliceDescendingStriped(b *testing.B) { + for n := 0; n < b.N; n++ { + bm := roaring.NewFileBitmap() + l := uint64(pilosa.ShardWidth / 8) + for col := uint64(l); col < l+1; col-- { + bm.Add(l*7 + col) + bm.Add(l*6 + col) + bm.Add(l*5 + col) + bm.Add(l*4 + col) + bm.Add(l*3 + col) + bm.Add(l*2 + col) + bm.Add(l*1 + col) + bm.Add(l*0 + col) + } } } From 3f6c17f4338996f28d65b3c51d20ad217d5cc8f0 Mon Sep 17 00:00:00 2001 From: Seebs Date: Mon, 26 Nov 2018 13:10:26 -0600 Subject: [PATCH 2/2] roaring: use DirectAdd rather than op.apply for cheap performance win MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Calling op.apply on an op we know to be an add ends up noticably increasing the cost of the operation; this trivial change gets about a 5-10% reduction in reported runtime of benchmarks doing a lot of adds. (The other IntersectionCount benchmarks don't actually use Add most of the time, so it doesn't show up in them.) name old time/op new time/op delta GetBenchData-8 4.25ms ± 0% 3.91ms ± 2% -8.04% (p=0.002 n=6+6) Bitmap_IntersectionCount_ArrayArray-8 20.9µs ± 2% 18.7µs ± 3% -10.18% (p=0.004 n=5+6) SliceAscending-8 24.7ms ± 0% 21.8ms ± 0% -11.74% (p=0.004 n=5+6) SliceDescending-8 29.8ms ± 0% 27.0ms ± 0% -9.56% (p=0.004 n=5+6) SliceAscendingStriped-8 32.0ms ± 0% 29.5ms ± 0% -8.07% (p=0.008 n=5+5) SliceDescendingStriped-8 39.3ms ± 1% 36.8ms ± 1% -6.27% (p=0.002 n=6+6) --- roaring/roaring.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/roaring/roaring.go b/roaring/roaring.go index 9c4274df9..c0d4cb996 100644 --- a/roaring/roaring.go +++ b/roaring/roaring.go @@ -159,9 +159,8 @@ func (b *Bitmap) Add(a ...uint64) (changed bool, err error) { } // Apply to the in-memory bitmap. - if op.apply(b) { + if b.DirectAdd(v) { changed = true - } }