benchmark_test.go 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. // Copyright (C) 2016 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 weakhash
  7. import (
  8. "bytes"
  9. "context"
  10. "fmt"
  11. "hash"
  12. vadler32 "hash/adler32"
  13. "io"
  14. "math/rand"
  15. "os"
  16. "testing"
  17. "github.com/chmduquesne/rollinghash/adler32"
  18. "github.com/chmduquesne/rollinghash/bozo32"
  19. "github.com/chmduquesne/rollinghash/buzhash32"
  20. "github.com/chmduquesne/rollinghash/buzhash64"
  21. )
  22. const testFile = "../model/testdata/tmpfile"
  23. const size = 128 << 10
  24. func BenchmarkFind1MFile(b *testing.B) {
  25. b.ReportAllocs()
  26. b.SetBytes(1 << 20)
  27. for i := 0; i < b.N; i++ {
  28. fd, err := os.Open(testFile)
  29. if err != nil {
  30. b.Fatal(err)
  31. }
  32. _, err = Find(context.Background(), fd, []uint32{0, 1, 2}, size)
  33. if err != nil {
  34. b.Fatal(err)
  35. }
  36. fd.Close()
  37. }
  38. }
  39. type RollingHash interface {
  40. hash.Hash
  41. Roll(byte)
  42. }
  43. func BenchmarkBlock(b *testing.B) {
  44. tests := []struct {
  45. name string
  46. hash hash.Hash
  47. }{
  48. {
  49. "adler32", adler32.New(),
  50. },
  51. {
  52. "bozo32", bozo32.New(),
  53. },
  54. {
  55. "buzhash32", buzhash32.New(),
  56. },
  57. {
  58. "buzhash64", buzhash64.New(),
  59. },
  60. {
  61. "vanilla-adler32", vadler32.New(),
  62. },
  63. }
  64. sizes := []int64{128 << 10, 16 << 20}
  65. buf := make([]byte, 16<<20)
  66. rand.Read(buf)
  67. for _, testSize := range sizes {
  68. for _, test := range tests {
  69. b.Run(test.name+"-"+fmt.Sprint(testSize), func(bb *testing.B) {
  70. bb.Run("", func(bbb *testing.B) {
  71. bbb.ResetTimer()
  72. for i := 0; i < bbb.N; i++ {
  73. lr := io.LimitReader(bytes.NewReader(buf), testSize)
  74. n, err := io.Copy(test.hash, lr)
  75. if err != nil {
  76. bbb.Error(err)
  77. }
  78. if n != testSize {
  79. bbb.Errorf("%d != %d", n, testSize)
  80. }
  81. test.hash.Sum(nil)
  82. test.hash.Reset()
  83. }
  84. bbb.SetBytes(testSize)
  85. bbb.ReportAllocs()
  86. })
  87. })
  88. }
  89. }
  90. }
  91. func BenchmarkRoll(b *testing.B) {
  92. tests := []struct {
  93. name string
  94. hash RollingHash
  95. }{
  96. {
  97. "adler32", adler32.New(),
  98. },
  99. {
  100. "bozo32", bozo32.New(),
  101. },
  102. {
  103. "buzhash32", buzhash32.New(),
  104. },
  105. {
  106. "buzhash64", buzhash64.New(),
  107. },
  108. }
  109. sizes := []int64{128 << 10, 16 << 20}
  110. for _, testSize := range sizes {
  111. for _, test := range tests {
  112. b.Run(test.name+"-"+fmt.Sprint(testSize), func(bb *testing.B) {
  113. bb.Run("", func(bbb *testing.B) {
  114. data := make([]byte, testSize)
  115. if _, err := test.hash.Write(data); err != nil {
  116. bbb.Error(err)
  117. }
  118. bbb.ResetTimer()
  119. for i := 0; i < bbb.N; i++ {
  120. for j := int64(0); j <= testSize; j++ {
  121. test.hash.Roll('a')
  122. }
  123. }
  124. bbb.SetBytes(testSize)
  125. bbb.ReportAllocs()
  126. })
  127. })
  128. }
  129. }
  130. }