diff --git a/benchmark_utils.go b/benchmark_utils.go new file mode 100644 index 0000000..9e812f9 --- /dev/null +++ b/benchmark_utils.go @@ -0,0 +1,74 @@ +package peerstore + +import ( + cr "crypto/rand" + "fmt" + "testing" + "time" + + "github.com/mr-tron/base58/base58" + ma "github.com/multiformats/go-multiaddr" + mh "github.com/multiformats/go-multihash" + "math/rand" +) + +type peerpair struct { + ID string + Addr ma.Multiaddr +} + +func randomPeer(b *testing.B) *peerpair { + buf := make([]byte, 50) + + for { + n, err := cr.Read(buf) + if err != nil { + b.Fatal(err) + } + if n > 0 { + break + } + } + + id, err := mh.Encode(buf, mh.SHA2_256) + if err != nil { + b.Fatal(err) + } + b58ID := base58.Encode(id) + + addr, err := ma.NewMultiaddr(fmt.Sprintf("/ip4/127.0.0.1/tcp/6666/ipfs/%s", b58ID)) + if err != nil { + b.Fatal(err) + } + + return &peerpair{b58ID, addr} +} + +func addressProducer(b *testing.B, addrs chan *peerpair, n int) { + defer close(addrs) + for i := 0; i < n; i++ { + p := randomPeer(b) + addrs <- p + } +} + +func rateLimitedAddressProducer(b *testing.B, addrs chan *peerpair, producer chan *peerpair, n int, avgTime time.Duration, errBound time.Duration) { + defer close(addrs) + + go addressProducer(b, producer, n) + + eb := int64(errBound) + for { + addr, ok := <-producer + if !ok { + break + } + addrs <- addr + wiggle := time.Duration(0) + if eb > 0 { + wiggle = time.Duration(rand.Int63n(eb*2) - eb) + } + sleepDur := avgTime + wiggle + time.Sleep(sleepDur) + } +} diff --git a/peerstore_test.go b/peerstore_test.go index 6c4d27c..a1e650e 100644 --- a/peerstore_test.go +++ b/peerstore_test.go @@ -269,3 +269,40 @@ func TestBasicPeerstore(t *testing.T) { t.Fatal("stored wrong address") } } + +func BenchmarkBasicPeerstore(b *testing.B) { + ps := NewPeerstore() + + addrs := make(chan *peerpair, 100) + + go addressProducer(b, addrs, 50000) + + b.ResetTimer() + for { + pp, ok := <-addrs + if !ok { + break + } + pid := peer.ID(pp.ID) + ps.AddAddr(pid, pp.Addr, PermanentAddrTTL) + } +} + +func BenchmarkBasicPeerstoreRateLimited(b *testing.B) { + ps := NewPeerstore() + + producer := make(chan *peerpair, 100) + addrs := make(chan *peerpair, 100) + + go rateLimitedAddressProducer(b, addrs, producer, 5000, time.Millisecond, 500 * time.Microsecond) + + b.ResetTimer() + for { + pp, ok := <-addrs + if !ok { + break + } + pid := peer.ID(pp.ID) + ps.AddAddr(pid, pp.Addr, PermanentAddrTTL) + } +} \ No newline at end of file