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