profile_test.go raw

   1  //go:build !js && !wasm && !tinygo && !wasm32
   2  
   3  package bench
   4  
   5  import (
   6  	"crypto/rand"
   7  	"os"
   8  	"path/filepath"
   9  	"runtime"
  10  	"runtime/pprof"
  11  	"testing"
  12  
  13  	"next.orly.dev/pkg/p256k1"
  14  )
  15  
  16  // Generate memory profiles for optimization
  17  
  18  func TestGenerateMemProfile(t *testing.T) {
  19  	// Setup
  20  	seckey := make([]byte, 32)
  21  	rand.Read(seckey)
  22  
  23  	kp, err := p256k1.KeyPairCreate(seckey)
  24  	if err != nil {
  25  		t.Fatal(err)
  26  	}
  27  
  28  	xonly, _ := kp.XOnlyPubkey()
  29  	pubkey := kp.Pubkey()
  30  
  31  	msg := make([]byte, 32)
  32  	rand.Read(msg)
  33  
  34  	var schnorrSig [64]byte
  35  	p256k1.SchnorrSign(schnorrSig[:], msg, kp, nil)
  36  
  37  	var ecdsaSig p256k1.ECDSASignature
  38  	p256k1.ECDSASign(&ecdsaSig, msg, seckey)
  39  
  40  	// Force GC to get clean state
  41  	runtime.GC()
  42  
  43  	// Create memory profile file
  44  	f, err := os.Create(filepath.Join(t.TempDir(), "mem.prof"))
  45  	if err != nil {
  46  		t.Fatal(err)
  47  	}
  48  	defer f.Close()
  49  
  50  	// Run operations many times to accumulate allocations
  51  	iterations := 10000
  52  
  53  	t.Log("Running Schnorr Sign...")
  54  	for i := 0; i < iterations; i++ {
  55  		p256k1.SchnorrSign(schnorrSig[:], msg, kp, nil)
  56  	}
  57  
  58  	t.Log("Running Schnorr Verify...")
  59  	for i := 0; i < iterations; i++ {
  60  		p256k1.SchnorrVerify(schnorrSig[:], msg, xonly)
  61  	}
  62  
  63  	t.Log("Running ECDSA Sign...")
  64  	for i := 0; i < iterations; i++ {
  65  		p256k1.ECDSASign(&ecdsaSig, msg, seckey)
  66  	}
  67  
  68  	t.Log("Running ECDSA Verify...")
  69  	for i := 0; i < iterations; i++ {
  70  		p256k1.ECDSAVerify(&ecdsaSig, msg, pubkey)
  71  	}
  72  
  73  	// Write heap profile
  74  	runtime.GC()
  75  	if err := pprof.WriteHeapProfile(f); err != nil {
  76  		t.Fatal(err)
  77  	}
  78  
  79  	t.Log("Memory profile written to", f.Name())
  80  }
  81  
  82  // TestAllocationsBreakdown shows allocation counts per operation
  83  func TestAllocationsBreakdown(t *testing.T) {
  84  	// Setup
  85  	seckey := make([]byte, 32)
  86  	rand.Read(seckey)
  87  
  88  	kp, err := p256k1.KeyPairCreate(seckey)
  89  	if err != nil {
  90  		t.Fatal(err)
  91  	}
  92  
  93  	xonly, _ := kp.XOnlyPubkey()
  94  	pubkey := kp.Pubkey()
  95  
  96  	msg := make([]byte, 32)
  97  	rand.Read(msg)
  98  
  99  	var schnorrSig [64]byte
 100  	p256k1.SchnorrSign(schnorrSig[:], msg, kp, nil)
 101  
 102  	var ecdsaSig p256k1.ECDSASignature
 103  	p256k1.ECDSASign(&ecdsaSig, msg, seckey)
 104  
 105  	// Measure allocations for each operation
 106  	var m1, m2 runtime.MemStats
 107  
 108  	// Schnorr Sign
 109  	runtime.GC()
 110  	runtime.ReadMemStats(&m1)
 111  	for i := 0; i < 1000; i++ {
 112  		p256k1.SchnorrSign(schnorrSig[:], msg, kp, nil)
 113  	}
 114  	runtime.ReadMemStats(&m2)
 115  	t.Logf("Schnorr Sign: %d allocs, %d bytes/op", (m2.Mallocs-m1.Mallocs)/1000, (m2.TotalAlloc-m1.TotalAlloc)/1000)
 116  
 117  	// Schnorr Verify
 118  	runtime.GC()
 119  	runtime.ReadMemStats(&m1)
 120  	for i := 0; i < 1000; i++ {
 121  		p256k1.SchnorrVerify(schnorrSig[:], msg, xonly)
 122  	}
 123  	runtime.ReadMemStats(&m2)
 124  	t.Logf("Schnorr Verify: %d allocs, %d bytes/op", (m2.Mallocs-m1.Mallocs)/1000, (m2.TotalAlloc-m1.TotalAlloc)/1000)
 125  
 126  	// ECDSA Sign
 127  	runtime.GC()
 128  	runtime.ReadMemStats(&m1)
 129  	for i := 0; i < 1000; i++ {
 130  		p256k1.ECDSASign(&ecdsaSig, msg, seckey)
 131  	}
 132  	runtime.ReadMemStats(&m2)
 133  	t.Logf("ECDSA Sign: %d allocs, %d bytes/op", (m2.Mallocs-m1.Mallocs)/1000, (m2.TotalAlloc-m1.TotalAlloc)/1000)
 134  
 135  	// ECDSA Verify
 136  	runtime.GC()
 137  	runtime.ReadMemStats(&m1)
 138  	for i := 0; i < 1000; i++ {
 139  		p256k1.ECDSAVerify(&ecdsaSig, msg, pubkey)
 140  	}
 141  	runtime.ReadMemStats(&m2)
 142  	t.Logf("ECDSA Verify: %d allocs, %d bytes/op", (m2.Mallocs-m1.Mallocs)/1000, (m2.TotalAlloc-m1.TotalAlloc)/1000)
 143  }
 144