@@ -11,6 +11,7 @@ import (
1111 "time"
1212
1313 "github.com/cockroachdb/pebble/internal/base"
14+ "github.com/cockroachdb/pebble/internal/crdbtest"
1415 "github.com/cockroachdb/pebble/internal/testkeys"
1516 "github.com/cockroachdb/pebble/sstable/block"
1617 "golang.org/x/exp/rand"
@@ -213,3 +214,131 @@ func BenchmarkBlockIterPrev(b *testing.B) {
213214 }
214215 }
215216}
217+
218+ func BenchmarkCockroachDataBlockWriter (b * testing.B ) {
219+ for _ , alphaLen := range []int {4 , 8 , 26 } {
220+ for _ , lenSharedPct := range []float64 {0.25 , 0.5 } {
221+ for _ , prefixLen := range []int {8 , 32 , 128 } {
222+ lenShared := int (float64 (prefixLen ) * lenSharedPct )
223+ for _ , valueLen := range []int {8 , 128 , 1024 } {
224+ keyConfig := crdbtest.KeyConfig {
225+ PrefixAlphabetLen : alphaLen ,
226+ PrefixLen : prefixLen ,
227+ PrefixLenShared : lenShared ,
228+ Logical : 0 ,
229+ BaseWallTime : uint64 (time .Now ().UnixNano ()),
230+ }
231+ b .Run (fmt .Sprintf ("%s,valueLen=%d" , keyConfig , valueLen ), func (b * testing.B ) {
232+ benchmarkCockroachDataBlockWriter (b , keyConfig , valueLen )
233+ })
234+ }
235+ }
236+ }
237+ }
238+ }
239+
240+ func benchmarkCockroachDataBlockWriter (b * testing.B , keyConfig crdbtest.KeyConfig , valueLen int ) {
241+ const targetBlockSize = 32 << 10
242+ seed := uint64 (time .Now ().UnixNano ())
243+ rng := rand .New (rand .NewSource (seed ))
244+ keys , values := crdbtest .RandomKVs (rng , targetBlockSize / valueLen , keyConfig , valueLen )
245+
246+ var w Writer
247+ w .RestartInterval = 16
248+ b .ResetTimer ()
249+ for i := 0 ; i < b .N ; i ++ {
250+ w .Reset ()
251+ var j int
252+ var prevKeyLen int
253+ for w .EstimatedSize () < targetBlockSize {
254+ ik := base .MakeInternalKey (keys [j ], base .SeqNum (rng .Uint64n (uint64 (base .SeqNumMax ))), base .InternalKeyKindSet )
255+ var samePrefix bool
256+ if j > 0 {
257+ samePrefix = bytes .Equal (keys [j ], keys [j - 1 ])
258+ }
259+ w .AddWithOptionalValuePrefix (
260+ ik , false , values [j ], prevKeyLen , true , block .InPlaceValuePrefix (samePrefix ), samePrefix )
261+ j ++
262+ prevKeyLen = len (ik .UserKey )
263+ }
264+ w .Finish ()
265+ }
266+ }
267+
268+ func BenchmarkCockroachDataBlockIter (b * testing.B ) {
269+ for _ , alphaLen := range []int {4 , 8 , 26 } {
270+ for _ , lenSharedPct := range []float64 {0.25 , 0.5 } {
271+ for _ , prefixLen := range []int {8 , 32 , 128 } {
272+ lenShared := int (float64 (prefixLen ) * lenSharedPct )
273+ for _ , logical := range []uint32 {0 , 1 } {
274+ for _ , valueLen := range []int {8 , 128 , 1024 } {
275+ keyConfig := crdbtest.KeyConfig {
276+ PrefixAlphabetLen : alphaLen ,
277+ PrefixLen : prefixLen ,
278+ PrefixLenShared : lenShared ,
279+ Logical : logical ,
280+ BaseWallTime : uint64 (time .Now ().UnixNano ()),
281+ }
282+ b .Run (fmt .Sprintf ("%s,value=%d" , keyConfig , valueLen ),
283+ func (b * testing.B ) {
284+ benchmarkCockroachDataBlockIter (b , keyConfig , valueLen )
285+ })
286+ }
287+ }
288+ }
289+ }
290+ }
291+ }
292+
293+ func benchmarkCockroachDataBlockIter (b * testing.B , keyConfig crdbtest.KeyConfig , valueLen int ) {
294+ const targetBlockSize = 32 << 10
295+ seed := uint64 (time .Now ().UnixNano ())
296+ rng := rand .New (rand .NewSource (seed ))
297+ keys , values := crdbtest .RandomKVs (rng , targetBlockSize / valueLen , keyConfig , valueLen )
298+
299+ var w Writer
300+ w .RestartInterval = 16
301+ var count int
302+ var prevKeyLen int
303+ for w .EstimatedSize () < targetBlockSize {
304+ ik := base .MakeInternalKey (keys [count ], base .SeqNum (rng .Uint64n (uint64 (base .SeqNumMax ))), base .InternalKeyKindSet )
305+ var samePrefix bool
306+ if count > 0 {
307+ samePrefix = bytes .Equal (keys [count ], keys [count - 1 ])
308+ }
309+ w .AddWithOptionalValuePrefix (
310+ ik , false , values [count ], prevKeyLen , true , block .InPlaceValuePrefix (samePrefix ), samePrefix )
311+ count ++
312+ prevKeyLen = len (ik .UserKey )
313+ }
314+ serializedBlock := w .Finish ()
315+ var it Iter
316+ it .Init (crdbtest .Compare , crdbtest .Split , serializedBlock , block .NoTransforms )
317+ avgRowSize := float64 (len (serializedBlock )) / float64 (count )
318+
319+ b .Run ("Next" , func (b * testing.B ) {
320+ kv := it .First ()
321+ b .ResetTimer ()
322+ for i := 0 ; i < b .N ; i ++ {
323+ if kv == nil {
324+ kv = it .First ()
325+ } else {
326+ kv = it .Next ()
327+ }
328+ }
329+ b .StopTimer ()
330+ b .ReportMetric (avgRowSize , "bytes/row" )
331+ })
332+ b .Run ("SeekGE" , func (b * testing.B ) {
333+ rng := rand .New (rand .NewSource (seed ))
334+ b .ResetTimer ()
335+ for i := 0 ; i < b .N ; i ++ {
336+ k := keys [rng .Intn (count )]
337+ if kv := it .SeekGE (k , base .SeekGEFlagsNone ); kv == nil {
338+ b .Fatalf ("%q not found" , k )
339+ }
340+ }
341+ b .StopTimer ()
342+ b .ReportMetric (avgRowSize , "bytes/row" )
343+ })
344+ }
0 commit comments