mirror of
https://github.com/octoleo/restic.git
synced 2024-12-26 20:30:19 +00:00
Parallel index benchmarks + benchmark optimizations
createRandomIndex was using the global RNG, which locks on every call It was also using twice as many random numbers as necessary and doing a float division in every iteration of the inner loop. BenchmarkDecodeIndex was using too short an input, especially for a parallel version. (It may now be using one that is a bit large.) Results on linux/amd64, -benchtime=3s -count=20: name old time/op new time/op delta PackerManager-8 178ms ± 0% 178ms ± 0% ~ (p=0.165 n=20+20) DecodeIndex-8 13.6µs ± 2% 4539886.8µs ± 0% +33293901.38% (p=0.000 n=20+18) IndexHasUnknown-8 44.4ns ± 7% 44.4ns ± 5% ~ (p=0.873 n=20+19) IndexHasKnown-8 49.2ns ± 3% 48.3ns ± 0% -1.86% (p=0.000 n=20+16) IndexAlloc-8 802ms ± 1% 758ms ± 1% -5.51% (p=0.000 n=20+19) MasterIndexLookupSingleIndex-8 124ns ± 1% 122ns ± 0% -1.41% (p=0.000 n=20+14) MasterIndexLookupMultipleIndex-8 373ns ± 2% 369ns ± 2% -1.13% (p=0.001 n=20+20) MasterIndexLookupSingleIndexUnknown-8 67.8ns ± 3% 68.4ns ± 5% ~ (p=0.753 n=20+20) MasterIndexLookupMultipleIndexUnknown-8 316ns ± 3% 315ns ± 3% ~ (p=0.846 n=20+20) SaveAndEncrypt-8 30.5ms ± 1% 30.2ms ± 1% -1.09% (p=0.000 n=19+19) LoadTree-8 527µs ± 1% 540µs ± 1% +2.37% (p=0.000 n=19+20) LoadBlob-8 5.65ms ± 0% 5.64ms ± 0% -0.21% (p=0.000 n=19+18) LoadAndDecrypt-8 7.07ms ± 2% 5.93ms ± 0% -16.15% (p=0.000 n=19+20) LoadIndex-8 32.1ms ± 2% 25.1ms ± 0% -21.64% (p=0.000 n=20+18) name old speed new speed delta PackerManager-8 296MB/s ± 0% 296MB/s ± 0% ~ (p=0.159 n=20+20) SaveAndEncrypt-8 138MB/s ± 1% 139MB/s ± 1% +1.10% (p=0.000 n=19+19) LoadBlob-8 177MB/s ± 0% 177MB/s ± 0% +0.21% (p=0.000 n=19+18) LoadAndDecrypt-8 141MB/s ± 2% 169MB/s ± 0% +19.24% (p=0.000 n=19+20) name old alloc/op new alloc/op delta PackerManager-8 91.8kB ± 0% 91.8kB ± 0% ~ (p=0.826 n=19+12) IndexAlloc-8 786MB ± 0% 786MB ± 0% +0.01% (p=0.000 n=20+20) SaveAndEncrypt-8 21.0MB ± 0% 21.0MB ± 0% -0.00% (p=0.012 n=20+19) name old allocs/op new allocs/op delta PackerManager-8 1.41k ± 0% 1.41k ± 0% ~ (all equal) IndexAlloc-8 977k ± 0% 977k ± 0% +0.01% (p=0.022 n=20+20) SaveAndEncrypt-8 73.0 ± 0% 73.0 ± 0% ~ (all equal)
This commit is contained in:
parent
02bec13ef2
commit
255ba83c4b
@ -3,6 +3,7 @@ package repository_test
|
||||
import (
|
||||
"bytes"
|
||||
"math/rand"
|
||||
"sync"
|
||||
"testing"
|
||||
|
||||
"github.com/restic/restic/internal/repository"
|
||||
@ -329,15 +330,40 @@ func TestIndexUnserialize(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
benchmarkIndexJSON []byte
|
||||
benchmarkIndexJSONOnce sync.Once
|
||||
)
|
||||
|
||||
func initBenchmarkIndexJSON() {
|
||||
idx, _ := createRandomIndex(rand.New(rand.NewSource(0)))
|
||||
var buf bytes.Buffer
|
||||
idx.Encode(&buf)
|
||||
benchmarkIndexJSON = buf.Bytes()
|
||||
}
|
||||
|
||||
func BenchmarkDecodeIndex(b *testing.B) {
|
||||
benchmarkIndexJSONOnce.Do(initBenchmarkIndexJSON)
|
||||
b.ResetTimer()
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
_, err := repository.DecodeIndex(docExample)
|
||||
_, err := repository.DecodeIndex(benchmarkIndexJSON)
|
||||
rtest.OK(b, err)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkDecodeIndexParallel(b *testing.B) {
|
||||
benchmarkIndexJSONOnce.Do(initBenchmarkIndexJSON)
|
||||
b.ResetTimer()
|
||||
|
||||
b.RunParallel(func(pb *testing.PB) {
|
||||
for pb.Next() {
|
||||
_, err := repository.DecodeIndex(benchmarkIndexJSON)
|
||||
rtest.OK(b, err)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestIndexUnserializeOld(t *testing.T) {
|
||||
idx, err := repository.DecodeOldIndex(docOldExample)
|
||||
rtest.OK(t, err)
|
||||
@ -401,7 +427,7 @@ func createRandomIndex(rng *rand.Rand) (idx *repository.Index, lookupID restic.I
|
||||
var blobs []restic.Blob
|
||||
offset := 0
|
||||
for offset < maxPackSize {
|
||||
size := 2000 + rand.Intn(4*1024*1024)
|
||||
size := 2000 + rng.Intn(4*1024*1024)
|
||||
id := NewRandomTestID(rng)
|
||||
blobs = append(blobs, restic.Blob{
|
||||
Type: restic.DataBlob,
|
||||
@ -411,12 +437,12 @@ func createRandomIndex(rng *rand.Rand) (idx *repository.Index, lookupID restic.I
|
||||
})
|
||||
|
||||
offset += size
|
||||
|
||||
if rand.Float32() < 0.001 && lookupID.IsNull() {
|
||||
lookupID = id
|
||||
}
|
||||
}
|
||||
idx.StorePack(packID, blobs)
|
||||
|
||||
if i == 0 {
|
||||
lookupID = blobs[rng.Intn(len(blobs))].ID
|
||||
}
|
||||
}
|
||||
|
||||
return idx, lookupID
|
||||
@ -444,12 +470,25 @@ func BenchmarkIndexHasKnown(b *testing.B) {
|
||||
}
|
||||
|
||||
func BenchmarkIndexAlloc(b *testing.B) {
|
||||
rng := rand.New(rand.NewSource(0))
|
||||
b.ReportAllocs()
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
createRandomIndex(rand.New(rand.NewSource(0)))
|
||||
createRandomIndex(rng)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkIndexAllocParallel(b *testing.B) {
|
||||
b.ReportAllocs()
|
||||
|
||||
b.RunParallel(func(pb *testing.PB) {
|
||||
rng := rand.New(rand.NewSource(0))
|
||||
for pb.Next() {
|
||||
createRandomIndex(rng)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestIndexHas(t *testing.T) {
|
||||
type testEntry struct {
|
||||
id restic.ID
|
||||
|
@ -1,6 +1,7 @@
|
||||
package repository_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"testing"
|
||||
|
||||
@ -74,11 +75,11 @@ func BenchmarkMasterIndexLookupMultipleIndex(b *testing.B) {
|
||||
mIdx := repository.NewMasterIndex()
|
||||
|
||||
for i := 0; i < 5; i++ {
|
||||
idx, _ := createRandomIndex(rand.New(rng))
|
||||
idx, _ := createRandomIndex(rng)
|
||||
mIdx.Insert(idx)
|
||||
}
|
||||
|
||||
idx1, lookupID := createRandomIndex(rand.New(rng))
|
||||
idx1, lookupID := createRandomIndex(rng)
|
||||
mIdx.Insert(idx1)
|
||||
|
||||
b.ResetTimer()
|
||||
@ -107,17 +108,51 @@ func BenchmarkMasterIndexLookupMultipleIndexUnknown(b *testing.B) {
|
||||
lookupID := restic.NewRandomID()
|
||||
mIdx := repository.NewMasterIndex()
|
||||
|
||||
for i := 0; i < 5; i++ {
|
||||
idx, _ := createRandomIndex(rand.New(rng))
|
||||
for i := 0; i < 6; i++ {
|
||||
idx, _ := createRandomIndex(rng)
|
||||
mIdx.Insert(idx)
|
||||
}
|
||||
|
||||
idx1, _ := createRandomIndex(rand.New(rng))
|
||||
mIdx.Insert(idx1)
|
||||
|
||||
b.ResetTimer()
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
mIdx.Lookup(lookupID, restic.DataBlob)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkMasterIndexLookupParallel(b *testing.B) {
|
||||
mIdx := repository.NewMasterIndex()
|
||||
|
||||
for _, numindices := range []int{5, 10, 20} {
|
||||
var lookupID restic.ID
|
||||
|
||||
b.StopTimer()
|
||||
rng := rand.New(rand.NewSource(0))
|
||||
for i := 0; i < numindices; i++ {
|
||||
var idx *repository.Index
|
||||
idx, lookupID = createRandomIndex(rng)
|
||||
mIdx.Insert(idx)
|
||||
}
|
||||
b.StartTimer()
|
||||
|
||||
name := fmt.Sprintf("known,indices=%d", numindices)
|
||||
b.Run(name, func(b *testing.B) {
|
||||
b.RunParallel(func(pb *testing.PB) {
|
||||
for pb.Next() {
|
||||
mIdx.Lookup(lookupID, restic.DataBlob)
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
lookupID = restic.NewRandomID()
|
||||
name = fmt.Sprintf("unknown,indices=%d", numindices)
|
||||
b.Run(name, func(b *testing.B) {
|
||||
b.RunParallel(func(pb *testing.PB) {
|
||||
for pb.Next() {
|
||||
mIdx.Lookup(lookupID, restic.DataBlob)
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user