benchmark_test.go 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. // Copyright (C) 2015 The Syncthing Authors.
  2. //
  3. // This Source Code Form is subject to the terms of the Mozilla Public
  4. // License, v. 2.0. If a copy of the MPL was not distributed with this file,
  5. // You can obtain one at http://mozilla.org/MPL/2.0/.
  6. // +build benchmark
  7. package db_test
  8. import (
  9. "fmt"
  10. "io/ioutil"
  11. "os"
  12. "path/filepath"
  13. "testing"
  14. "github.com/syncthing/syncthing/lib/db"
  15. "github.com/syncthing/syncthing/lib/protocol"
  16. "github.com/syndtr/goleveldb/leveldb"
  17. "github.com/syndtr/goleveldb/leveldb/opt"
  18. )
  19. var files, oneFile, firstHalf, secondHalf []protocol.FileInfo
  20. var fs *db.FileSet
  21. func init() {
  22. for i := 0; i < 1000; i++ {
  23. files = append(files, protocol.FileInfo{
  24. Name: fmt.Sprintf("file%d", i),
  25. Version: protocol.Vector{{ID: myID, Value: 1000}},
  26. Blocks: genBlocks(i),
  27. })
  28. }
  29. middle := len(files) / 2
  30. firstHalf = files[:middle]
  31. secondHalf = files[middle:]
  32. oneFile = firstHalf[middle-1 : middle]
  33. ldb, _ := tempDB()
  34. fs = db.NewFileSet("test", ldb)
  35. fs.Replace(remoteDevice0, files)
  36. fs.Replace(protocol.LocalDeviceID, firstHalf)
  37. }
  38. func tempDB() (*leveldb.DB, string) {
  39. dir, err := ioutil.TempDir("", "syncthing")
  40. if err != nil {
  41. panic(err)
  42. }
  43. db, err := leveldb.OpenFile(filepath.Join(dir, "db"), &opt.Options{OpenFilesCacheCapacity: 100})
  44. if err != nil {
  45. panic(err)
  46. }
  47. return db, dir
  48. }
  49. func BenchmarkReplaceAll(b *testing.B) {
  50. ldb, dir := tempDB()
  51. defer func() {
  52. ldb.Close()
  53. os.RemoveAll(dir)
  54. }()
  55. b.ResetTimer()
  56. for i := 0; i < b.N; i++ {
  57. m := db.NewFileSet("test", ldb)
  58. m.Replace(protocol.LocalDeviceID, files)
  59. }
  60. b.ReportAllocs()
  61. }
  62. func BenchmarkUpdateOneChanged(b *testing.B) {
  63. changed := make([]protocol.FileInfo, 1)
  64. changed[0] = oneFile[0]
  65. changed[0].Version = changed[0].Version.Update(myID)
  66. changed[0].Blocks = genBlocks(len(changed[0].Blocks))
  67. for i := 0; i < b.N; i++ {
  68. if i%1 == 0 {
  69. fs.Update(protocol.LocalDeviceID, changed)
  70. } else {
  71. fs.Update(protocol.LocalDeviceID, oneFile)
  72. }
  73. }
  74. b.ReportAllocs()
  75. }
  76. func BenchmarkUpdateOneUnchanged(b *testing.B) {
  77. for i := 0; i < b.N; i++ {
  78. fs.Update(protocol.LocalDeviceID, oneFile)
  79. }
  80. b.ReportAllocs()
  81. }
  82. func BenchmarkNeedHalf(b *testing.B) {
  83. for i := 0; i < b.N; i++ {
  84. count := 0
  85. fs.WithNeed(protocol.LocalDeviceID, func(fi db.FileIntf) bool {
  86. count++
  87. return true
  88. })
  89. if count != len(secondHalf) {
  90. b.Errorf("wrong length %d != %d", count, len(secondHalf))
  91. }
  92. }
  93. b.ReportAllocs()
  94. }
  95. func BenchmarkHave(b *testing.B) {
  96. for i := 0; i < b.N; i++ {
  97. count := 0
  98. fs.WithHave(protocol.LocalDeviceID, func(fi db.FileIntf) bool {
  99. count++
  100. return true
  101. })
  102. if count != len(firstHalf) {
  103. b.Errorf("wrong length %d != %d", count, len(firstHalf))
  104. }
  105. }
  106. b.ReportAllocs()
  107. }
  108. func BenchmarkGlobal(b *testing.B) {
  109. for i := 0; i < b.N; i++ {
  110. count := 0
  111. fs.WithGlobal(func(fi db.FileIntf) bool {
  112. count++
  113. return true
  114. })
  115. if count != len(files) {
  116. b.Errorf("wrong length %d != %d", count, len(files))
  117. }
  118. }
  119. b.ReportAllocs()
  120. }
  121. func BenchmarkNeedHalfTruncated(b *testing.B) {
  122. for i := 0; i < b.N; i++ {
  123. count := 0
  124. fs.WithNeedTruncated(protocol.LocalDeviceID, func(fi db.FileIntf) bool {
  125. count++
  126. return true
  127. })
  128. if count != len(secondHalf) {
  129. b.Errorf("wrong length %d != %d", count, len(secondHalf))
  130. }
  131. }
  132. b.ReportAllocs()
  133. }
  134. func BenchmarkHaveTruncated(b *testing.B) {
  135. for i := 0; i < b.N; i++ {
  136. count := 0
  137. fs.WithHaveTruncated(protocol.LocalDeviceID, func(fi db.FileIntf) bool {
  138. count++
  139. return true
  140. })
  141. if count != len(firstHalf) {
  142. b.Errorf("wrong length %d != %d", count, len(firstHalf))
  143. }
  144. }
  145. b.ReportAllocs()
  146. }
  147. func BenchmarkGlobalTruncated(b *testing.B) {
  148. for i := 0; i < b.N; i++ {
  149. count := 0
  150. fs.WithGlobalTruncated(func(fi db.FileIntf) bool {
  151. count++
  152. return true
  153. })
  154. if count != len(files) {
  155. b.Errorf("wrong length %d != %d", count, len(files))
  156. }
  157. }
  158. b.ReportAllocs()
  159. }