mirror of
https://github.com/featurebasedb/featurebase.git
synced 2026-09-07 09:05:55 +00:00
tweak ImportValue benchmark
With timestamps, we probably want to at least check larger BSI fields, so we add that. Also, tweak the interpretation of b.N (making each N count for 10,000 bits) so we can see allocation load at all. But we also reduce the sparse set to be about one bit per 19 bits, because if we do one per 70,000, and are doing field-at-a-time imports, we're getting hundreds of imports to try to match a target of, say, around a million values. We also sort the inputs, because ImportValue is about to start requiring that, since the API does it anyway. Also, extend this to be available on Fields, because field.ImportValue is ALSO doing things which could be inefficient or expensive.
This commit is contained in:
parent
7fe37a83f4
commit
671a0cf5c6
2 changed files with 73 additions and 17 deletions
|
|
@ -203,7 +203,7 @@ type TestField struct {
|
|||
}
|
||||
|
||||
// NewTestField returns a new instance of TestField d/0.
|
||||
func NewTestField(t *testing.T, opts FieldOption) *TestField {
|
||||
func NewTestField(t testing.TB, opts FieldOption) *TestField {
|
||||
path, err := testhook.TempDirInDir(t, *TempDir, "pilosa-field-")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
|
|
@ -230,7 +230,7 @@ func NewTestField(t *testing.T, opts FieldOption) *TestField {
|
|||
}
|
||||
|
||||
// OpenField returns a new, opened field at a temporary path.
|
||||
func OpenField(t *testing.T, opts FieldOption) *TestField {
|
||||
func OpenField(t testing.TB, opts FieldOption) *TestField {
|
||||
f := NewTestField(t, opts)
|
||||
return f
|
||||
}
|
||||
|
|
@ -509,6 +509,38 @@ func TestBSIGroup_importValue(t *testing.T) {
|
|||
} // loop
|
||||
}
|
||||
|
||||
// benchmarkImportValues is a helper function to explore, very roughly, the cost
|
||||
// of setting values using the special setter used for imports.
|
||||
func benchmarkFieldImportValues(b *testing.B, qcx *Qcx, bitDepth uint64, f *TestField, cfunc func(uint64) uint64) {
|
||||
batches := makeBenchmarkImportValueData(b, bitDepth, cfunc)
|
||||
for _, req := range batches {
|
||||
err := f.importValue(qcx, req.ColumnIDs, req.Values, &ImportOptions{})
|
||||
if err != nil {
|
||||
b.Fatalf("error importing values: %s", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Benchmark performance of setValue for BSI ranges.
|
||||
func BenchmarkField_ImportValue(b *testing.B) {
|
||||
depths := []uint64{4, 8, 16, 32}
|
||||
|
||||
for _, bitDepth := range depths {
|
||||
f := OpenField(b, OptFieldTypeInt(0, 1<<bitDepth))
|
||||
defer f.Close()
|
||||
|
||||
qcx := f.idx.holder.txf.NewQcx()
|
||||
defer qcx.Abort()
|
||||
name := fmt.Sprintf("Depth%d", bitDepth)
|
||||
b.Run(name+"_Sparse", func(b *testing.B) {
|
||||
benchmarkFieldImportValues(b, qcx, bitDepth, f, func(u uint64) uint64 { return (u + 19) & (ShardWidth - 1) })
|
||||
})
|
||||
b.Run(name+"_Dense", func(b *testing.B) {
|
||||
benchmarkFieldImportValues(b, qcx, bitDepth, f, func(u uint64) uint64 { return (u + 1) & (ShardWidth - 1) })
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestIntField_MinMaxForShard(t *testing.T) {
|
||||
f := OpenField(t, OptFieldTypeInt(-100, 200))
|
||||
defer f.Close()
|
||||
|
|
|
|||
|
|
@ -1020,34 +1020,58 @@ func BenchmarkFragment_SetValue(b *testing.B) {
|
|||
}
|
||||
}
|
||||
|
||||
func makeBenchmarkImportValueData(b *testing.B, bitDepth uint64, cfunc func(uint64) uint64) []ImportValueRequest {
|
||||
b.StopTimer()
|
||||
column := uint64(0)
|
||||
// we don't average an alloc-per-bit, so we use a much larger N to get
|
||||
// meaningful data from -benchmem
|
||||
n := b.N * 10000
|
||||
batches := make([]ImportValueRequest, 0, (n/ShardWidth)+1)
|
||||
mask := int64(1<<bitDepth) - 1
|
||||
prev := uint64(0)
|
||||
var values []int64
|
||||
var columns []uint64
|
||||
for i := 0; i < n; i++ {
|
||||
values = append(values, int64(i)&mask)
|
||||
columns = append(columns, column)
|
||||
column = cfunc(column)
|
||||
if column < prev {
|
||||
req := ImportValueRequest{ColumnIDs: columns, Values: values}
|
||||
columns = []uint64{}
|
||||
values = []int64{}
|
||||
batches = append(batches, req)
|
||||
}
|
||||
prev = column
|
||||
}
|
||||
if len(columns) > 0 {
|
||||
req := ImportValueRequest{ColumnIDs: columns, Values: values}
|
||||
batches = append(batches, req)
|
||||
}
|
||||
b.StartTimer()
|
||||
return batches
|
||||
}
|
||||
|
||||
// benchmarkImportValues is a helper function to explore, very roughly, the cost
|
||||
// of setting values using the special setter used for imports.
|
||||
func benchmarkImportValues(b *testing.B, tx Tx, bitDepth uint64, f *fragment, cfunc func(uint64) uint64) {
|
||||
column := uint64(0)
|
||||
b.StopTimer()
|
||||
columns := make([]uint64, b.N)
|
||||
values := make([]int64, b.N)
|
||||
for i := 0; i < b.N; i++ {
|
||||
values[i] = int64(i)
|
||||
columns[i] = column
|
||||
column = cfunc(column)
|
||||
}
|
||||
b.StartTimer()
|
||||
err := f.importValue(tx, columns, values, bitDepth, false)
|
||||
if err != nil {
|
||||
b.Fatalf("error importing values: %s", err)
|
||||
batches := makeBenchmarkImportValueData(b, bitDepth, cfunc)
|
||||
for _, req := range batches {
|
||||
err := f.importValue(tx, req.ColumnIDs, req.Values, bitDepth, false)
|
||||
if err != nil {
|
||||
b.Fatalf("error importing values: %s", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Benchmark performance of setValue for BSI ranges.
|
||||
func BenchmarkFragment_ImportValue(b *testing.B) {
|
||||
depths := []uint64{4, 8, 16}
|
||||
depths := []uint64{4, 8, 16, 32}
|
||||
for _, bitDepth := range depths {
|
||||
name := fmt.Sprintf("Depth%d", bitDepth)
|
||||
f, idx, tx := mustOpenBSIFragment(b, "i", "f", viewBSIGroupPrefix+"foo", 0)
|
||||
_ = idx
|
||||
b.Run(name+"_Sparse", func(b *testing.B) {
|
||||
benchmarkImportValues(b, tx, bitDepth, f, func(u uint64) uint64 { return (u + 70000) & (ShardWidth - 1) })
|
||||
benchmarkImportValues(b, tx, bitDepth, f, func(u uint64) uint64 { return (u + 19) & (ShardWidth - 1) })
|
||||
})
|
||||
f.Clean(b)
|
||||
f, idx, tx = mustOpenBSIFragment(b, "i", "f", viewBSIGroupPrefix+"foo", 0)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue