mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-19 18:32:23 +00:00
swarm/storage/localstore: add retrieval tests benchmarks
This commit is contained in:
parent
d58e1ee5e0
commit
f2299f4703
2 changed files with 180 additions and 0 deletions
|
|
@ -205,6 +205,22 @@ func generateFakeRandomChunk() storage.Chunk {
|
||||||
func TestGenerateFakeRandomChunk(t *testing.T) {
|
func TestGenerateFakeRandomChunk(t *testing.T) {
|
||||||
c1 := generateFakeRandomChunk()
|
c1 := generateFakeRandomChunk()
|
||||||
c2 := generateFakeRandomChunk()
|
c2 := generateFakeRandomChunk()
|
||||||
|
addrLen := len(c1.Address())
|
||||||
|
if addrLen != 32 {
|
||||||
|
t.Errorf("first chunk address length %v, want %v", addrLen, 32)
|
||||||
|
}
|
||||||
|
dataLen := len(c1.Data())
|
||||||
|
if dataLen != ch.DefaultSize {
|
||||||
|
t.Errorf("first chunk data length %v, want %v", dataLen, ch.DefaultSize)
|
||||||
|
}
|
||||||
|
addrLen = len(c2.Address())
|
||||||
|
if addrLen != 32 {
|
||||||
|
t.Errorf("second chunk address length %v, want %v", addrLen, 32)
|
||||||
|
}
|
||||||
|
dataLen = len(c2.Data())
|
||||||
|
if dataLen != ch.DefaultSize {
|
||||||
|
t.Errorf("second chunk data length %v, want %v", dataLen, ch.DefaultSize)
|
||||||
|
}
|
||||||
if bytes.Equal(c1.Address(), c2.Address()) {
|
if bytes.Equal(c1.Address(), c2.Address()) {
|
||||||
t.Error("fake chunks addresses do not differ")
|
t.Error("fake chunks addresses do not differ")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
164
swarm/storage/localstore/retrieval_index_test.go
Normal file
164
swarm/storage/localstore/retrieval_index_test.go
Normal file
|
|
@ -0,0 +1,164 @@
|
||||||
|
// Copyright 2018 The go-ethereum Authors
|
||||||
|
// This file is part of the go-ethereum library.
|
||||||
|
//
|
||||||
|
// The go-ethereum library is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// The go-ethereum library is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Lesser General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public License
|
||||||
|
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
package localstore
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"strconv"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/swarm/storage"
|
||||||
|
)
|
||||||
|
|
||||||
|
// BenchmarkRetrievalIndexes compares two different retrieval
|
||||||
|
// index schemas:
|
||||||
|
// - single retrieval composite index retrievalCompositeIndex
|
||||||
|
// - two separated indexes for data and access time
|
||||||
|
// - retrievalDataIndex
|
||||||
|
// - retrievalAccessIndex
|
||||||
|
// This benchmark uploads a number of chunks in order to measure
|
||||||
|
// total time of updating their retrieval indexes by setting them
|
||||||
|
// to synced state and requesting them.
|
||||||
|
//
|
||||||
|
// This benchmark takes significant amount of time.
|
||||||
|
//
|
||||||
|
// Measurements on MacBook Pro (Retina, 15-inch, Mid 2014) show
|
||||||
|
// that two separated indexes perform better.
|
||||||
|
//
|
||||||
|
// # go test -benchmem -run=none github.com/ethereum/go-ethereum/swarm/storage/localstore -bench BenchmarkRetrievalIndexes -v
|
||||||
|
// goos: darwin
|
||||||
|
// goarch: amd64
|
||||||
|
// pkg: github.com/ethereum/go-ethereum/swarm/storage/localstore
|
||||||
|
// BenchmarkRetrievalIndexes/1000-split-8 20 57035332 ns/op 18150318 B/op 78152 allocs/op
|
||||||
|
// BenchmarkRetrievalIndexes/1000-composite-8 10 145093830 ns/op 66965899 B/op 68621 allocs/op
|
||||||
|
// BenchmarkRetrievalIndexes/10000-split-8 1 1023919551 ns/op 376620048 B/op 1384874 allocs/op
|
||||||
|
// BenchmarkRetrievalIndexes/10000-composite-8 1 2612845197 ns/op 1006614104 B/op 1492380 allocs/op
|
||||||
|
// BenchmarkRetrievalIndexes/100000-split-8 1 14168164804 ns/op 2868944816 B/op 12425362 allocs/op
|
||||||
|
// BenchmarkRetrievalIndexes/100000-composite-8 1 65995988337 ns/op 12387004776 B/op 22376909 allocs/op
|
||||||
|
// PASS
|
||||||
|
func BenchmarkRetrievalIndexes(b *testing.B) {
|
||||||
|
for _, count := range []int{
|
||||||
|
1000,
|
||||||
|
10000,
|
||||||
|
100000,
|
||||||
|
} {
|
||||||
|
b.Run(strconv.Itoa(count)+"-split", func(b *testing.B) {
|
||||||
|
for n := 0; n < b.N; n++ {
|
||||||
|
benchmarkRetrievalIndexes(b, nil, count)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
b.Run(strconv.Itoa(count)+"-composite", func(b *testing.B) {
|
||||||
|
for n := 0; n < b.N; n++ {
|
||||||
|
benchmarkRetrievalIndexes(b, &Options{UseRetrievalCompositeIndex: true}, count)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// benchmarkRetrievalIndexes is used in BenchmarkRetrievalIndexes
|
||||||
|
// to do benchmarks with a specific number of chunks and different
|
||||||
|
// database options.
|
||||||
|
func benchmarkRetrievalIndexes(b *testing.B, o *Options, count int) {
|
||||||
|
b.StopTimer()
|
||||||
|
db, cleanupFunc := newTestDB(b, o)
|
||||||
|
defer cleanupFunc()
|
||||||
|
uploader := db.Accessor(ModeUpload)
|
||||||
|
syncer := db.Accessor(ModeSynced)
|
||||||
|
requester := db.Accessor(ModeRequest)
|
||||||
|
ctx := context.Background()
|
||||||
|
chunks := make([]storage.Chunk, count)
|
||||||
|
for i := 0; i < count; i++ {
|
||||||
|
chunk := generateFakeRandomChunk()
|
||||||
|
err := uploader.Put(ctx, chunk)
|
||||||
|
if err != nil {
|
||||||
|
b.Fatal(err)
|
||||||
|
}
|
||||||
|
chunks[i] = chunk
|
||||||
|
}
|
||||||
|
b.StartTimer()
|
||||||
|
|
||||||
|
for i := 0; i < count; i++ {
|
||||||
|
err := syncer.Put(ctx, chunks[i])
|
||||||
|
if err != nil {
|
||||||
|
b.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = requester.Get(ctx, chunks[i].Address())
|
||||||
|
if err != nil {
|
||||||
|
b.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// BenchmarkUpload compares uploading speed for different
|
||||||
|
// retrieval indexes and various number of chunks.
|
||||||
|
//
|
||||||
|
// Measurements on MacBook Pro (Retina, 15-inch, Mid 2014).
|
||||||
|
//
|
||||||
|
// go test -benchmem -run=none github.com/ethereum/go-ethereum/swarm/storage/localstore -bench BenchmarkUpload -v
|
||||||
|
// goos: darwin
|
||||||
|
// goarch: amd64
|
||||||
|
// pkg: github.com/ethereum/go-ethereum/swarm/storage/localstore
|
||||||
|
// BenchmarkUpload/1000-split-8 20 99501623 ns/op 25164178 B/op 22202 allocs/op
|
||||||
|
// BenchmarkUpload/1000-composite-8 20 103449118 ns/op 25177986 B/op 22204 allocs/op
|
||||||
|
// BenchmarkUpload/10000-split-8 2 670290376 ns/op 216382840 B/op 239645 allocs/op
|
||||||
|
// BenchmarkUpload/10000-composite-8 2 667137525 ns/op 216377176 B/op 238854 allocs/op
|
||||||
|
// BenchmarkUpload/100000-split-8 1 26074429894 ns/op 2326850952 B/op 3932893 allocs/op
|
||||||
|
// BenchmarkUpload/100000-composite-8 1 26242346728 ns/op 2331055096 B/op 3957569 allocs/op
|
||||||
|
// PASS
|
||||||
|
func BenchmarkUpload(b *testing.B) {
|
||||||
|
for _, count := range []int{
|
||||||
|
1000,
|
||||||
|
10000,
|
||||||
|
100000,
|
||||||
|
} {
|
||||||
|
b.Run(strconv.Itoa(count)+"-split", func(b *testing.B) {
|
||||||
|
for n := 0; n < b.N; n++ {
|
||||||
|
benchmarkUpload(b, nil, count)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
b.Run(strconv.Itoa(count)+"-composite", func(b *testing.B) {
|
||||||
|
for n := 0; n < b.N; n++ {
|
||||||
|
benchmarkUpload(b, &Options{UseRetrievalCompositeIndex: true}, count)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// benchmarkUpload is used in BenchmarkUpload
|
||||||
|
// to do benchmarks with a specific number of chunks and different
|
||||||
|
// database options.
|
||||||
|
func benchmarkUpload(b *testing.B, o *Options, count int) {
|
||||||
|
b.StopTimer()
|
||||||
|
db, cleanupFunc := newTestDB(b, o)
|
||||||
|
defer cleanupFunc()
|
||||||
|
uploader := db.Accessor(ModeUpload)
|
||||||
|
ctx := context.Background()
|
||||||
|
chunks := make([]storage.Chunk, count)
|
||||||
|
for i := 0; i < count; i++ {
|
||||||
|
chunk := generateFakeRandomChunk()
|
||||||
|
chunks[i] = chunk
|
||||||
|
}
|
||||||
|
b.StartTimer()
|
||||||
|
|
||||||
|
for i := 0; i < count; i++ {
|
||||||
|
err := uploader.Put(ctx, chunks[i])
|
||||||
|
if err != nil {
|
||||||
|
b.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in a new issue