Improve benchmarks and fix bitvector iterator

License: MIT
Signed-off-by: Jakub Sztandera <kubuxu@protonmail.ch>
This commit is contained in:
Jakub Sztandera 2019-09-22 13:50:43 +02:00 committed by Jakub Sztandera
parent 9bf871ee53
commit 3d6071ed3f
No known key found for this signature in database
GPG Key ID: 9A9AF56F8B3879BA
4 changed files with 63 additions and 17 deletions

View File

@ -173,7 +173,6 @@ func (v *BitVector) Iterator(order BitNumbering) func(uint) byte {
// Here be dragons // Here be dragons
// This is about 10x faster // This is about 10x faster
index := int(0) index := int(0)
bitIdx := uint(0)
var rest uint64 var rest uint64
for n := 7; n >= 0; n-- { for n := 7; n >= 0; n-- {
@ -186,16 +185,17 @@ func (v *BitVector) Iterator(order BitNumbering) func(uint) byte {
index++ index++
} }
bitCap := uint(64)
return func(bits uint) (out byte) { return func(bits uint) (out byte) {
if bits > 8 { if bits > 8 {
log.Panicf("invalid count") log.Panicf("invalid count")
} }
res := byte(rest) & masks[bits] res := byte(rest) & masks[bits]
rest = rest >> bits rest = rest >> bits
bitIdx = bitIdx + bits bitCap = bitCap - bits
if bitIdx > (64 - 8) { if bitCap < 8 {
bitIdx = bitIdx & 7
var add uint64 var add uint64
for n := 6; n >= 0; n-- { for n := 6; n >= 0; n-- {
@ -207,7 +207,8 @@ func (v *BitVector) Iterator(order BitNumbering) func(uint) byte {
add = add<<8 | o add = add<<8 | o
} }
index = index + 7 index = index + 7
rest = rest | add<<(8-bitIdx) rest = rest | add<<(bitCap)
bitCap = bitCap + 7*8
} }
return res return res

View File

@ -100,8 +100,8 @@ func TestBitVector(t *testing.T) {
var buf []byte var buf []byte
// make a bitvector of 256 sample bits // make a bitvector of 256 sample bits
for i := 0; i < 32; i++ { for i := 0; i < 1000; i++ {
buf = append(buf, byte(128+i)) buf = append(buf, byte(i))
} }
v := bitvector.NewBitVector(buf, bitvector.LSB0) v := bitvector.NewBitVector(buf, bitvector.LSB0)

File diff suppressed because one or more lines are too long

View File

@ -2,7 +2,6 @@ package rlepluslazy
import ( import (
"math/rand" "math/rand"
"runtime"
"testing" "testing"
"github.com/filecoin-project/go-lotus/extern/rleplus" "github.com/filecoin-project/go-lotus/extern/rleplus"
@ -47,11 +46,11 @@ func TestDecode(t *testing.T) {
assert.Equal(t, expectedNumbers, decoded) assert.Equal(t, expectedNumbers, decoded)
} }
func TestGolden(t *testing.T) { func TestGoldenGen(t *testing.T) {
t.SkipNow() t.SkipNow()
N := 1000 N := 10000
mod := uint32(1) << 16 mod := uint32(1) << 20
runExProp := float32(0.9) runExProp := float32(0.93)
bits := make([]uint64, N) bits := make([]uint64, N)
@ -70,39 +69,85 @@ func TestGolden(t *testing.T) {
t.Logf("%#v", out) t.Logf("%#v", out)
_, runs := rleplus.RunLengths(bits) _, runs := rleplus.RunLengths(bits)
t.Logf("runs: %v", runs) t.Logf("runs: %v", runs)
t.Logf("len: %d", len(out))
} }
func TestGolden(t *testing.T) {
expected, _ := rleplus.Decode(goldenRLE)
res := make([]uint64, 0, len(expected))
rle, err := FromBuf(goldenRLE)
assert.NoError(t, err)
rit, err := rle.RunIterator()
assert.NoError(t, err)
it, err := BitsFromRuns(rit)
assert.NoError(t, err)
for it.HasNext() {
bit, err := it.Next()
assert.NoError(t, err)
res = append(res, bit)
}
assert.Equal(t, expected, res)
}
var Res uint64 = 0
func BenchmarkIterator(b *testing.B) { func BenchmarkIterator(b *testing.B) {
b.ReportAllocs()
var r uint64
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
rle, _ := FromBuf(goldenRLE) rle, _ := FromBuf(goldenRLE)
it, _ := rle.Iterator() it, _ := rle.Iterator()
for it.HasNext() { for it.HasNext() {
bit, _ := it.Next() bit, _ := it.Next()
runtime.KeepAlive(bit) if bit < 1<<63 {
r++
} }
} }
}
Res = Res + r
} }
func BenchmarkRunIterator(b *testing.B) { func BenchmarkRunIterator(b *testing.B) {
b.ReportAllocs()
var r uint64
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
rle, _ := FromBuf(goldenRLE) rle, _ := FromBuf(goldenRLE)
rit, _ := rle.RunIterator() rit, _ := rle.RunIterator()
for rit.HasNext() { for rit.HasNext() {
run, _ := rit.NextRun() run, _ := rit.NextRun()
runtime.KeepAlive(run) if run.Val {
r = r + run.Len
} }
} }
}
Res = Res + r
} }
func BenchmarkRunsToBits(b *testing.B) { func BenchmarkRunsToBits(b *testing.B) {
b.ReportAllocs()
var r uint64
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
rle, _ := FromBuf(goldenRLE) rle, _ := FromBuf(goldenRLE)
rit, _ := rle.RunIterator() rit, _ := rle.RunIterator()
it, _ := BitsFromRuns(rit) it, _ := BitsFromRuns(rit)
for it.HasNext() { for it.HasNext() {
bit, _ := it.Next() bit, _ := it.Next()
runtime.KeepAlive(bit) if bit < 1<<63 {
r++
} }
} }
}
Res = Res + r
}
func BenchmarkOldRLE(b *testing.B) {
b.ReportAllocs()
var r uint64
for i := 0; i < b.N; i++ {
rle, _ := rleplus.Decode(goldenRLE)
r = r + uint64(len(rle))
}
Res = Res + r
} }