mirror of
https://github.com/octoleo/syncthing.git
synced 2025-01-08 17:24:08 +00:00
Make benchmarks more realistic
This commit is contained in:
parent
058a327584
commit
943e80e26c
199
lib/db/benchmark_test.go
Normal file
199
lib/db/benchmark_test.go
Normal file
@ -0,0 +1,199 @@
|
|||||||
|
// Copyright (C) 2015 The Syncthing Authors.
|
||||||
|
//
|
||||||
|
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||||
|
// You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
|
||||||
|
package db_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/syncthing/syncthing/lib/db"
|
||||||
|
"github.com/syncthing/syncthing/lib/protocol"
|
||||||
|
"github.com/syndtr/goleveldb/leveldb"
|
||||||
|
"github.com/syndtr/goleveldb/leveldb/opt"
|
||||||
|
)
|
||||||
|
|
||||||
|
var files, oneFile, firstHalf, secondHalf []protocol.FileInfo
|
||||||
|
var fs *db.FileSet
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
for i := 0; i < 1000; i++ {
|
||||||
|
files = append(files, protocol.FileInfo{
|
||||||
|
Name: fmt.Sprintf("file%d", i),
|
||||||
|
Version: protocol.Vector{{ID: myID, Value: 1000}},
|
||||||
|
Blocks: genBlocks(i),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
middle := len(files) / 2
|
||||||
|
firstHalf = files[:middle]
|
||||||
|
secondHalf = files[middle:]
|
||||||
|
oneFile = firstHalf[middle-1 : middle]
|
||||||
|
|
||||||
|
ldb, _ := tempDB()
|
||||||
|
fs = db.NewFileSet("test", ldb)
|
||||||
|
fs.Replace(remoteDevice0, files)
|
||||||
|
fs.Replace(protocol.LocalDeviceID, firstHalf)
|
||||||
|
}
|
||||||
|
|
||||||
|
func genBlocks(n int) []protocol.BlockInfo {
|
||||||
|
b := make([]protocol.BlockInfo, n)
|
||||||
|
for i := range b {
|
||||||
|
h := make([]byte, 32)
|
||||||
|
for j := range h {
|
||||||
|
h[j] = byte(i + j)
|
||||||
|
}
|
||||||
|
b[i].Size = int32(i)
|
||||||
|
b[i].Hash = h
|
||||||
|
}
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
func tempDB() (*leveldb.DB, string) {
|
||||||
|
dir, err := ioutil.TempDir("", "syncthing")
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
db, err := leveldb.OpenFile(filepath.Join(dir, "db"), &opt.Options{OpenFilesCacheCapacity: 100})
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return db, dir
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkReplaceAll(b *testing.B) {
|
||||||
|
ldb, dir := tempDB()
|
||||||
|
defer func() {
|
||||||
|
ldb.Close()
|
||||||
|
os.RemoveAll(dir)
|
||||||
|
}()
|
||||||
|
|
||||||
|
b.ResetTimer()
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
m := db.NewFileSet("test", ldb)
|
||||||
|
m.Replace(protocol.LocalDeviceID, files)
|
||||||
|
}
|
||||||
|
|
||||||
|
b.ReportAllocs()
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkUpdateOneChanged(b *testing.B) {
|
||||||
|
changed := make([]protocol.FileInfo, 1)
|
||||||
|
changed[0] = oneFile[0]
|
||||||
|
changed[0].Version = changed[0].Version.Update(myID)
|
||||||
|
changed[0].Blocks = genBlocks(len(changed[0].Blocks))
|
||||||
|
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
if i%1 == 0 {
|
||||||
|
fs.Update(protocol.LocalDeviceID, changed)
|
||||||
|
} else {
|
||||||
|
fs.Update(protocol.LocalDeviceID, oneFile)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
b.ReportAllocs()
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkUpdateOneUnchanged(b *testing.B) {
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
fs.Update(protocol.LocalDeviceID, oneFile)
|
||||||
|
}
|
||||||
|
|
||||||
|
b.ReportAllocs()
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkNeedHalf(b *testing.B) {
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
count := 0
|
||||||
|
fs.WithNeed(protocol.LocalDeviceID, func(fi db.FileIntf) bool {
|
||||||
|
count++
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
if count != len(secondHalf) {
|
||||||
|
b.Errorf("wrong length %d != %d", count, len(secondHalf))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
b.ReportAllocs()
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkHave(b *testing.B) {
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
count := 0
|
||||||
|
fs.WithHave(protocol.LocalDeviceID, func(fi db.FileIntf) bool {
|
||||||
|
count++
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
if count != len(firstHalf) {
|
||||||
|
b.Errorf("wrong length %d != %d", count, len(firstHalf))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
b.ReportAllocs()
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkGlobal(b *testing.B) {
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
count := 0
|
||||||
|
fs.WithGlobal(func(fi db.FileIntf) bool {
|
||||||
|
count++
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
if count != len(files) {
|
||||||
|
b.Errorf("wrong length %d != %d", count, len(files))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
b.ReportAllocs()
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkNeedHalfTruncated(b *testing.B) {
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
count := 0
|
||||||
|
fs.WithNeedTruncated(protocol.LocalDeviceID, func(fi db.FileIntf) bool {
|
||||||
|
count++
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
if count != len(secondHalf) {
|
||||||
|
b.Errorf("wrong length %d != %d", count, len(secondHalf))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
b.ReportAllocs()
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkHaveTruncated(b *testing.B) {
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
count := 0
|
||||||
|
fs.WithHaveTruncated(protocol.LocalDeviceID, func(fi db.FileIntf) bool {
|
||||||
|
count++
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
if count != len(firstHalf) {
|
||||||
|
b.Errorf("wrong length %d != %d", count, len(firstHalf))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
b.ReportAllocs()
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkGlobalTruncated(b *testing.B) {
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
count := 0
|
||||||
|
fs.WithGlobalTruncated(func(fi db.FileIntf) bool {
|
||||||
|
count++
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
if count != len(files) {
|
||||||
|
b.Errorf("wrong length %d != %d", count, len(files))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
b.ReportAllocs()
|
||||||
|
}
|
@ -28,19 +28,6 @@ func init() {
|
|||||||
|
|
||||||
const myID = 1
|
const myID = 1
|
||||||
|
|
||||||
func genBlocks(n int) []protocol.BlockInfo {
|
|
||||||
b := make([]protocol.BlockInfo, n)
|
|
||||||
for i := range b {
|
|
||||||
h := make([]byte, 32)
|
|
||||||
for j := range h {
|
|
||||||
h[j] = byte(i + j)
|
|
||||||
}
|
|
||||||
b[i].Size = int32(i)
|
|
||||||
b[i].Hash = h
|
|
||||||
}
|
|
||||||
return b
|
|
||||||
}
|
|
||||||
|
|
||||||
func globalList(s *db.FileSet) []protocol.FileInfo {
|
func globalList(s *db.FileSet) []protocol.FileInfo {
|
||||||
var fs []protocol.FileInfo
|
var fs []protocol.FileInfo
|
||||||
s.WithGlobal(func(fi db.FileIntf) bool {
|
s.WithGlobal(func(fi db.FileIntf) bool {
|
||||||
@ -417,180 +404,6 @@ func TestInvalidAvailability(t *testing.T) {
|
|||||||
t.Error("Incorrect availability for 'none':", av)
|
t.Error("Incorrect availability for 'none':", av)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
func Benchmark10kReplace(b *testing.B) {
|
|
||||||
ldb, err := leveldb.Open(storage.NewMemStorage(), nil)
|
|
||||||
if err != nil {
|
|
||||||
b.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
var local []protocol.FileInfo
|
|
||||||
for i := 0; i < 10000; i++ {
|
|
||||||
local = append(local, protocol.FileInfo{Name: fmt.Sprintf("file%d", i), Version: protocol.Vector{{ID: myID, Value: 1000}}})
|
|
||||||
}
|
|
||||||
|
|
||||||
b.ResetTimer()
|
|
||||||
for i := 0; i < b.N; i++ {
|
|
||||||
m := db.NewFileSet("test", ldb)
|
|
||||||
m.Replace(protocol.LocalDeviceID, local)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func Benchmark10kUpdateChg(b *testing.B) {
|
|
||||||
var remote []protocol.FileInfo
|
|
||||||
for i := 0; i < 10000; i++ {
|
|
||||||
remote = append(remote, protocol.FileInfo{Name: fmt.Sprintf("file%d", i), Version: protocol.Vector{{ID: myID, Value: 1000}}})
|
|
||||||
}
|
|
||||||
|
|
||||||
ldb, err := leveldb.Open(storage.NewMemStorage(), nil)
|
|
||||||
if err != nil {
|
|
||||||
b.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
m := db.NewFileSet("test", ldb)
|
|
||||||
m.Replace(remoteDevice0, remote)
|
|
||||||
|
|
||||||
var local []protocol.FileInfo
|
|
||||||
for i := 0; i < 10000; i++ {
|
|
||||||
local = append(local, protocol.FileInfo{Name: fmt.Sprintf("file%d", i), Version: protocol.Vector{{ID: myID, Value: 1000}}})
|
|
||||||
}
|
|
||||||
|
|
||||||
m.Replace(protocol.LocalDeviceID, local)
|
|
||||||
|
|
||||||
b.ResetTimer()
|
|
||||||
for i := 0; i < b.N; i++ {
|
|
||||||
b.StopTimer()
|
|
||||||
for j := range local {
|
|
||||||
local[j].Version = local[j].Version.Update(myID)
|
|
||||||
}
|
|
||||||
b.StartTimer()
|
|
||||||
m.Update(protocol.LocalDeviceID, local)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func Benchmark10kUpdateSme(b *testing.B) {
|
|
||||||
var remote []protocol.FileInfo
|
|
||||||
for i := 0; i < 10000; i++ {
|
|
||||||
remote = append(remote, protocol.FileInfo{Name: fmt.Sprintf("file%d", i), Version: protocol.Vector{{ID: myID, Value: 1000}}})
|
|
||||||
}
|
|
||||||
|
|
||||||
ldb, err := leveldb.Open(storage.NewMemStorage(), nil)
|
|
||||||
if err != nil {
|
|
||||||
b.Fatal(err)
|
|
||||||
}
|
|
||||||
m := db.NewFileSet("test", ldb)
|
|
||||||
m.Replace(remoteDevice0, remote)
|
|
||||||
|
|
||||||
var local []protocol.FileInfo
|
|
||||||
for i := 0; i < 10000; i++ {
|
|
||||||
local = append(local, protocol.FileInfo{Name: fmt.Sprintf("file%d", i), Version: protocol.Vector{{ID: myID, Value: 1000}}})
|
|
||||||
}
|
|
||||||
|
|
||||||
m.Replace(protocol.LocalDeviceID, local)
|
|
||||||
|
|
||||||
b.ResetTimer()
|
|
||||||
for i := 0; i < b.N; i++ {
|
|
||||||
m.Update(protocol.LocalDeviceID, local)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func Benchmark10kNeed2k(b *testing.B) {
|
|
||||||
var remote []protocol.FileInfo
|
|
||||||
for i := 0; i < 10000; i++ {
|
|
||||||
remote = append(remote, protocol.FileInfo{Name: fmt.Sprintf("file%d", i), Version: protocol.Vector{{ID: myID, Value: 1000}}})
|
|
||||||
}
|
|
||||||
|
|
||||||
ldb, err := leveldb.Open(storage.NewMemStorage(), nil)
|
|
||||||
if err != nil {
|
|
||||||
b.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
m := db.NewFileSet("test", ldb)
|
|
||||||
m.Replace(remoteDevice0, remote)
|
|
||||||
|
|
||||||
var local []protocol.FileInfo
|
|
||||||
for i := 0; i < 8000; i++ {
|
|
||||||
local = append(local, protocol.FileInfo{Name: fmt.Sprintf("file%d", i), Version: protocol.Vector{{ID: myID, Value: 1000}}})
|
|
||||||
}
|
|
||||||
for i := 8000; i < 10000; i++ {
|
|
||||||
local = append(local, protocol.FileInfo{Name: fmt.Sprintf("file%d", i), Version: protocol.Vector{{1, 980}}})
|
|
||||||
}
|
|
||||||
|
|
||||||
m.Replace(protocol.LocalDeviceID, local)
|
|
||||||
|
|
||||||
b.ResetTimer()
|
|
||||||
for i := 0; i < b.N; i++ {
|
|
||||||
fs := needList(m, protocol.LocalDeviceID)
|
|
||||||
if l := len(fs); l != 2000 {
|
|
||||||
b.Errorf("wrong length %d != 2k", l)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func Benchmark10kHaveFullList(b *testing.B) {
|
|
||||||
var remote []protocol.FileInfo
|
|
||||||
for i := 0; i < 10000; i++ {
|
|
||||||
remote = append(remote, protocol.FileInfo{Name: fmt.Sprintf("file%d", i), Version: protocol.Vector{{ID: myID, Value: 1000}}})
|
|
||||||
}
|
|
||||||
|
|
||||||
ldb, err := leveldb.Open(storage.NewMemStorage(), nil)
|
|
||||||
if err != nil {
|
|
||||||
b.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
m := db.NewFileSet("test", ldb)
|
|
||||||
m.Replace(remoteDevice0, remote)
|
|
||||||
|
|
||||||
var local []protocol.FileInfo
|
|
||||||
for i := 0; i < 2000; i++ {
|
|
||||||
local = append(local, protocol.FileInfo{Name: fmt.Sprintf("file%d", i), Version: protocol.Vector{{ID: myID, Value: 1000}}})
|
|
||||||
}
|
|
||||||
for i := 2000; i < 10000; i++ {
|
|
||||||
local = append(local, protocol.FileInfo{Name: fmt.Sprintf("file%d", i), Version: protocol.Vector{{1, 980}}})
|
|
||||||
}
|
|
||||||
|
|
||||||
m.Replace(protocol.LocalDeviceID, local)
|
|
||||||
|
|
||||||
b.ResetTimer()
|
|
||||||
for i := 0; i < b.N; i++ {
|
|
||||||
fs := haveList(m, protocol.LocalDeviceID)
|
|
||||||
if l := len(fs); l != 10000 {
|
|
||||||
b.Errorf("wrong length %d != 10k", l)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func Benchmark10kGlobal(b *testing.B) {
|
|
||||||
var remote []protocol.FileInfo
|
|
||||||
for i := 0; i < 10000; i++ {
|
|
||||||
remote = append(remote, protocol.FileInfo{Name: fmt.Sprintf("file%d", i), Version: protocol.Vector{{ID: myID, Value: 1000}}})
|
|
||||||
}
|
|
||||||
|
|
||||||
ldb, err := leveldb.Open(storage.NewMemStorage(), nil)
|
|
||||||
if err != nil {
|
|
||||||
b.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
m := db.NewFileSet("test", ldb)
|
|
||||||
m.Replace(remoteDevice0, remote)
|
|
||||||
|
|
||||||
var local []protocol.FileInfo
|
|
||||||
for i := 0; i < 2000; i++ {
|
|
||||||
local = append(local, protocol.FileInfo{Name: fmt.Sprintf("file%d", i), Version: protocol.Vector{{ID: myID, Value: 1000}}})
|
|
||||||
}
|
|
||||||
for i := 2000; i < 10000; i++ {
|
|
||||||
local = append(local, protocol.FileInfo{Name: fmt.Sprintf("file%d", i), Version: protocol.Vector{{1, 980}}})
|
|
||||||
}
|
|
||||||
|
|
||||||
m.Replace(protocol.LocalDeviceID, local)
|
|
||||||
|
|
||||||
b.ResetTimer()
|
|
||||||
for i := 0; i < b.N; i++ {
|
|
||||||
fs := globalList(m)
|
|
||||||
if l := len(fs); l != 10000 {
|
|
||||||
b.Errorf("wrong length %d != 10k", l)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestGlobalReset(t *testing.T) {
|
func TestGlobalReset(t *testing.T) {
|
||||||
ldb, err := leveldb.Open(storage.NewMemStorage(), nil)
|
ldb, err := leveldb.Open(storage.NewMemStorage(), nil)
|
||||||
|
Loading…
Reference in New Issue
Block a user