From 311809b079f4e839bfa815fb6986f713841644e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Mart=C3=AD?= Date: Tue, 27 Jul 2021 13:36:43 +0100 Subject: [PATCH] add the first read-only benchmarks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BenchmarkReadBlocks uses carv2.OpenReader with its Roots and Next method. From six runs on a laptop with a i5-8350U and benchstat: name time/op ReadBlocks-8 633µs ± 2% name speed ReadBlocks-8 824MB/s ± 2% name alloc/op ReadBlocks-8 1.32MB ± 0% name allocs/op ReadBlocks-8 13.5k ± 0% OpenReadOnlyV1 uses blockstore.OpenReadOnly with its Get method. The method is used on all blocks in a shuffled order, to ensure that the index is working as intended. The input file lacks an index, so we also generate that. name time/op OpenReadOnlyV1-8 899µs ± 1% name speed OpenReadOnlyV1-8 534MB/s ± 1% name alloc/op OpenReadOnlyV1-8 1.52MB ± 0% name allocs/op OpenReadOnlyV1-8 27.2k ± 0% Both benchmarks use the "sample" v1/v2 CAR files, which weigh about half a megabyte. It seems like a good size; a significantly larger CAR file would make each benchmark iteration take tens or hundreds of milliseconds, making it much slower to obtain many benchmark results, since we want at least thousands of iterations to avoid noise. --- v2/bench_test.go | 48 +++++++++++++++++++++++++ v2/blockstore/bench_test.go | 71 +++++++++++++++++++++++++++++++++++++ 2 files changed, 119 insertions(+) create mode 100644 v2/bench_test.go create mode 100644 v2/blockstore/bench_test.go diff --git a/v2/bench_test.go b/v2/bench_test.go new file mode 100644 index 0000000..c1fe5b6 --- /dev/null +++ b/v2/bench_test.go @@ -0,0 +1,48 @@ +package car_test + +import ( + "io" + "os" + "testing" + + carv2 "github.com/ipld/go-car/v2" +) + +// Open a reader, get the roots, and iterate over all blocks. +// Essentially looking at the contents of any CARv1 or CARv2 file. +// Note that this also uses ReadVersion underneath. + +func BenchmarkReadBlocks(b *testing.B) { + path := "testdata/sample-wrapped-v2.car" + + info, err := os.Stat(path) + if err != nil { + b.Fatal(err) + } + b.SetBytes(info.Size()) + b.ReportAllocs() + + b.RunParallel(func(pb *testing.PB) { + for pb.Next() { + cr, err := carv2.OpenReader(path) + if err != nil { + b.Fatal(err) + } + _, err = cr.Roots() + if err != nil { + b.Fatal(err) + } + for { + _, err := cr.Next() + if err == io.EOF { + break + } + if err != nil { + b.Fatal(err) + } + } + + cr.Close() + } + }) +} diff --git a/v2/blockstore/bench_test.go b/v2/blockstore/bench_test.go new file mode 100644 index 0000000..c97dc35 --- /dev/null +++ b/v2/blockstore/bench_test.go @@ -0,0 +1,71 @@ +package blockstore_test + +import ( + "io" + mathrand "math/rand" + "os" + "testing" + + "github.com/ipfs/go-cid" + carv2 "github.com/ipld/go-car/v2" + "github.com/ipld/go-car/v2/blockstore" +) + +// Open a read-only blockstore, +// and retrieve all blocks in a shuffled order. +// Note that this benchmark includes generating an index, +// since the input file is a CARv1. + +func BenchmarkOpenReadOnlyV1(b *testing.B) { + path := "../testdata/sample-v1.car" + + info, err := os.Stat(path) + if err != nil { + b.Fatal(err) + } + b.SetBytes(info.Size()) + b.ReportAllocs() + + var shuffledCIDs []cid.Cid + cr, err := carv2.OpenReader(path) + if err != nil { + b.Fatal(err) + } + for { + block, err := cr.Next() + if err == io.EOF { + break + } + if err != nil { + b.Fatal(err) + } + shuffledCIDs = append(shuffledCIDs, block.Cid()) + } + cr.Close() + + // The shuffling needs to be deterministic, + // for the sake of stable benchmark results. + // Any source number works as long as it's fixed. + rnd := mathrand.New(mathrand.NewSource(123456)) + rnd.Shuffle(len(shuffledCIDs), func(i, j int) { + shuffledCIDs[i], shuffledCIDs[j] = shuffledCIDs[j], shuffledCIDs[i] + }) + + b.RunParallel(func(pb *testing.PB) { + for pb.Next() { + bs, err := blockstore.OpenReadOnly(path) + if err != nil { + b.Fatal(err) + } + + for _, c := range shuffledCIDs { + _, err := bs.Get(c) + if err != nil { + b.Fatal(err) + } + } + + bs.Close() + } + }) +} -- GitLab