benchmark_test.go 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  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 https://mozilla.org/MPL/2.0/.
  6. package db_test
  7. import (
  8. "fmt"
  9. "testing"
  10. "github.com/syncthing/syncthing/lib/db"
  11. "github.com/syncthing/syncthing/lib/fs"
  12. "github.com/syncthing/syncthing/lib/protocol"
  13. )
  14. var files, oneFile, firstHalf, secondHalf []protocol.FileInfo
  15. var benchS *db.FileSet
  16. func lazyInitBenchFileSet() {
  17. if benchS != nil {
  18. return
  19. }
  20. for i := 0; i < 1000; i++ {
  21. files = append(files, protocol.FileInfo{
  22. Name: fmt.Sprintf("file%d", i),
  23. Version: protocol.Vector{Counters: []protocol.Counter{{ID: myID, Value: 1000}}},
  24. Blocks: genBlocks(i),
  25. })
  26. }
  27. middle := len(files) / 2
  28. firstHalf = files[:middle]
  29. secondHalf = files[middle:]
  30. oneFile = firstHalf[middle-1 : middle]
  31. ldb := db.OpenMemory()
  32. benchS = db.NewFileSet("test)", fs.NewFilesystem(fs.FilesystemTypeBasic, "."), ldb)
  33. replace(benchS, remoteDevice0, files)
  34. replace(benchS, protocol.LocalDeviceID, firstHalf)
  35. }
  36. func BenchmarkReplaceAll(b *testing.B) {
  37. ldb := db.OpenMemory()
  38. defer ldb.Close()
  39. b.ResetTimer()
  40. for i := 0; i < b.N; i++ {
  41. m := db.NewFileSet("test)", fs.NewFilesystem(fs.FilesystemTypeBasic, "."), ldb)
  42. replace(m, protocol.LocalDeviceID, files)
  43. }
  44. b.ReportAllocs()
  45. }
  46. func BenchmarkUpdateOneChanged(b *testing.B) {
  47. lazyInitBenchFileSet()
  48. changed := make([]protocol.FileInfo, 1)
  49. changed[0] = oneFile[0]
  50. changed[0].Version = changed[0].Version.Copy().Update(myID)
  51. b.ResetTimer()
  52. for i := 0; i < b.N; i++ {
  53. if i%2 == 0 {
  54. benchS.Update(protocol.LocalDeviceID, changed)
  55. } else {
  56. benchS.Update(protocol.LocalDeviceID, oneFile)
  57. }
  58. }
  59. b.ReportAllocs()
  60. }
  61. func BenchmarkUpdate100Changed(b *testing.B) {
  62. lazyInitBenchFileSet()
  63. unchanged := files[100:200]
  64. changed := append([]protocol.FileInfo{}, unchanged...)
  65. for i := range changed {
  66. changed[i].Version = changed[i].Version.Copy().Update(myID)
  67. }
  68. b.ResetTimer()
  69. for i := 0; i < b.N; i++ {
  70. if i%2 == 0 {
  71. benchS.Update(protocol.LocalDeviceID, changed)
  72. } else {
  73. benchS.Update(protocol.LocalDeviceID, unchanged)
  74. }
  75. }
  76. b.ReportAllocs()
  77. }
  78. func BenchmarkUpdate100ChangedRemote(b *testing.B) {
  79. lazyInitBenchFileSet()
  80. unchanged := files[100:200]
  81. changed := append([]protocol.FileInfo{}, unchanged...)
  82. for i := range changed {
  83. changed[i].Version = changed[i].Version.Copy().Update(myID)
  84. }
  85. b.ResetTimer()
  86. for i := 0; i < b.N; i++ {
  87. if i%2 == 0 {
  88. benchS.Update(remoteDevice0, changed)
  89. } else {
  90. benchS.Update(remoteDevice0, unchanged)
  91. }
  92. }
  93. b.ReportAllocs()
  94. }
  95. func BenchmarkUpdateOneUnchanged(b *testing.B) {
  96. lazyInitBenchFileSet()
  97. b.ResetTimer()
  98. for i := 0; i < b.N; i++ {
  99. benchS.Update(protocol.LocalDeviceID, oneFile)
  100. }
  101. b.ReportAllocs()
  102. }
  103. func BenchmarkNeedHalf(b *testing.B) {
  104. lazyInitBenchFileSet()
  105. b.ResetTimer()
  106. for i := 0; i < b.N; i++ {
  107. count := 0
  108. benchS.WithNeed(protocol.LocalDeviceID, func(fi db.FileIntf) bool {
  109. count++
  110. return true
  111. })
  112. if count != len(secondHalf) {
  113. b.Errorf("wrong length %d != %d", count, len(secondHalf))
  114. }
  115. }
  116. b.ReportAllocs()
  117. }
  118. func BenchmarkNeedHalfRemote(b *testing.B) {
  119. lazyInitBenchFileSet()
  120. ldb := db.OpenMemory()
  121. defer ldb.Close()
  122. fset := db.NewFileSet("test)", fs.NewFilesystem(fs.FilesystemTypeBasic, "."), ldb)
  123. replace(fset, remoteDevice0, firstHalf)
  124. replace(fset, protocol.LocalDeviceID, files)
  125. b.ResetTimer()
  126. for i := 0; i < b.N; i++ {
  127. count := 0
  128. fset.WithNeed(remoteDevice0, func(fi db.FileIntf) bool {
  129. count++
  130. return true
  131. })
  132. if count != len(secondHalf) {
  133. b.Errorf("wrong length %d != %d", count, len(secondHalf))
  134. }
  135. }
  136. b.ReportAllocs()
  137. }
  138. func BenchmarkHave(b *testing.B) {
  139. lazyInitBenchFileSet()
  140. b.ResetTimer()
  141. for i := 0; i < b.N; i++ {
  142. count := 0
  143. benchS.WithHave(protocol.LocalDeviceID, func(fi db.FileIntf) bool {
  144. count++
  145. return true
  146. })
  147. if count != len(firstHalf) {
  148. b.Errorf("wrong length %d != %d", count, len(firstHalf))
  149. }
  150. }
  151. b.ReportAllocs()
  152. }
  153. func BenchmarkGlobal(b *testing.B) {
  154. lazyInitBenchFileSet()
  155. b.ResetTimer()
  156. for i := 0; i < b.N; i++ {
  157. count := 0
  158. benchS.WithGlobal(func(fi db.FileIntf) bool {
  159. count++
  160. return true
  161. })
  162. if count != len(files) {
  163. b.Errorf("wrong length %d != %d", count, len(files))
  164. }
  165. }
  166. b.ReportAllocs()
  167. }
  168. func BenchmarkNeedHalfTruncated(b *testing.B) {
  169. lazyInitBenchFileSet()
  170. b.ResetTimer()
  171. for i := 0; i < b.N; i++ {
  172. count := 0
  173. benchS.WithNeedTruncated(protocol.LocalDeviceID, func(fi db.FileIntf) bool {
  174. count++
  175. return true
  176. })
  177. if count != len(secondHalf) {
  178. b.Errorf("wrong length %d != %d", count, len(secondHalf))
  179. }
  180. }
  181. b.ReportAllocs()
  182. }
  183. func BenchmarkHaveTruncated(b *testing.B) {
  184. lazyInitBenchFileSet()
  185. b.ResetTimer()
  186. for i := 0; i < b.N; i++ {
  187. count := 0
  188. benchS.WithHaveTruncated(protocol.LocalDeviceID, func(fi db.FileIntf) bool {
  189. count++
  190. return true
  191. })
  192. if count != len(firstHalf) {
  193. b.Errorf("wrong length %d != %d", count, len(firstHalf))
  194. }
  195. }
  196. b.ReportAllocs()
  197. }
  198. func BenchmarkGlobalTruncated(b *testing.B) {
  199. lazyInitBenchFileSet()
  200. b.ResetTimer()
  201. for i := 0; i < b.N; i++ {
  202. count := 0
  203. benchS.WithGlobalTruncated(func(fi db.FileIntf) bool {
  204. count++
  205. return true
  206. })
  207. if count != len(files) {
  208. b.Errorf("wrong length %d != %d", count, len(files))
  209. }
  210. }
  211. b.ReportAllocs()
  212. }