diff --git a/internal/repository/index_test.go b/internal/repository/index_test.go index c96101906..513f4c5d1 100644 --- a/internal/repository/index_test.go +++ b/internal/repository/index_test.go @@ -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 diff --git a/internal/repository/master_index_test.go b/internal/repository/master_index_test.go index 7dfcdda5f..3b858253a 100644 --- a/internal/repository/master_index_test.go +++ b/internal/repository/master_index_test.go @@ -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) + } + }) + }) + + } +}