github.com/ipld/go-ipld-prime@v0.21.0/storage/tests/benchmarks.go (about)

     1  package tests
     2  
     3  import (
     4  	"context"
     5  	"testing"
     6  
     7  	"github.com/ipld/go-ipld-prime/storage"
     8  )
     9  
    10  /*
    11  	General note:
    12  	It's important to be careful to benchmark the cost *per op* --
    13  	and not mistake b.N for the scale of corpus to work on.
    14  	The corpus size should be a parameter that you supply,
    15  	and your benchmark table should have a column for them!
    16  */
    17  
    18  func BenchPut(b *testing.B, store storage.WritableStorage, gen Gen, scale int) {
    19  	b.ReportAllocs()
    20  	b.Logf("benchmarking with b.N=%d", b.N)
    21  
    22  	// Use a fixed context throughout; it's not really relevant.
    23  	ctx := context.Background()
    24  
    25  	// Setup phase: create data up to the scale provided.
    26  	// Reset the timer afterwards.
    27  	b.Logf("prepopulating %d entries into storage...", scale)
    28  	for n := 0; n < scale; n++ {
    29  		key, content := gen()
    30  		err := store.Put(ctx, key, content)
    31  		if err != nil {
    32  			b.Fatal(err)
    33  		}
    34  	}
    35  	b.Logf("prepopulating %d entries into storage: done.", scale)
    36  	b.ResetTimer()
    37  
    38  	// Now continue doing puts in the benchmark loop.
    39  	// Note that if 'scale' was initially small, and b.N is big, results may be skewed,
    40  	//  because the last put of the series will actually be working at scale+b.N-1.
    41  	for n := 0; n < b.N; n++ {
    42  		// Attempt to avoid counting any time spent by the gen func.
    43  		//  ... except don't, because the overhead of starting and stopping is actually really high compared to a likely gen function;
    44  		//   in practice, starting and stopping this frequently causes:
    45  		//    - alloc count to be reported *correctly* (which is nice)
    46  		//    - but reported ns/op to become erratic, and inflated (not at all nice)
    47  		//    - and actuall wall-clock run time to increase drastically (~22x!) (not deadly, but certainly unpleasant)
    48  		//   It may be best to write a synthetic dummy benchmark to see how much the gen function costs, and subtract that from the other results.
    49  		//b.StopTimer()
    50  		key, content := gen()
    51  		//b.StartTimer()
    52  
    53  		// Do the put.
    54  		err := store.Put(ctx, key, content)
    55  		if err != nil {
    56  			b.Fatal(err)
    57  		}
    58  	}
    59  }