You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
279 lines
5.6 KiB
279 lines
5.6 KiB
package event |
|
|
|
import ( |
|
"bytes" |
|
"testing" |
|
"time" |
|
|
|
"next.orly.dev/pkg/crypto/p256k" |
|
"next.orly.dev/pkg/encoders/hex" |
|
"next.orly.dev/pkg/encoders/kind" |
|
"next.orly.dev/pkg/encoders/tag" |
|
"lukechampine.com/frand" |
|
) |
|
|
|
// createTestEvent creates a realistic test event with proper signing |
|
func createTestEvent() *E { |
|
signer := &p256k.Signer{} |
|
if err := signer.Generate(); err != nil { |
|
panic(err) |
|
} |
|
|
|
ev := New() |
|
ev.Pubkey = signer.Pub() |
|
ev.CreatedAt = time.Now().Unix() |
|
ev.Kind = kind.TextNote.K |
|
|
|
// Create realistic tags |
|
ev.Tags = tag.NewS( |
|
tag.NewFromBytesSlice([]byte("t"), []byte("hashtag")), |
|
tag.NewFromBytesSlice([]byte("e"), hex.EncAppend(nil, frand.Bytes(32))), |
|
tag.NewFromBytesSlice([]byte("p"), hex.EncAppend(nil, frand.Bytes(32))), |
|
) |
|
|
|
// Create realistic content |
|
ev.Content = []byte(`This is a test event with some content that includes special characters like < > & and "quotes" and various other things that might need escaping.`) |
|
|
|
// Sign the event |
|
if err := ev.Sign(signer); err != nil { |
|
panic(err) |
|
} |
|
|
|
return ev |
|
} |
|
|
|
// createLargeTestEvent creates a larger event with more tags and content |
|
func createLargeTestEvent() *E { |
|
signer := &p256k.Signer{} |
|
if err := signer.Generate(); err != nil { |
|
panic(err) |
|
} |
|
|
|
ev := New() |
|
ev.Pubkey = signer.Pub() |
|
ev.CreatedAt = time.Now().Unix() |
|
ev.Kind = kind.TextNote.K |
|
|
|
// Create many tags |
|
tags := tag.NewS() |
|
for i := 0; i < 20; i++ { |
|
tags.Append(tag.NewFromBytesSlice( |
|
[]byte("t"), |
|
[]byte("hashtag" + string(rune('0'+i))), |
|
)) |
|
if i%3 == 0 { |
|
tags.Append(tag.NewFromBytesSlice( |
|
[]byte("e"), |
|
hex.EncAppend(nil, frand.Bytes(32)), |
|
)) |
|
} |
|
} |
|
ev.Tags = tags |
|
|
|
// Large content |
|
content := make([]byte, 0, 4096) |
|
for i := 0; i < 50; i++ { |
|
content = append(content, []byte("This is a longer piece of content that simulates real-world event content. ")...) |
|
if i%10 == 0 { |
|
content = append(content, []byte("With special chars: < > & \" ' ")...) |
|
} |
|
} |
|
ev.Content = content |
|
|
|
// Sign the event |
|
if err := ev.Sign(signer); err != nil { |
|
panic(err) |
|
} |
|
|
|
return ev |
|
} |
|
|
|
// BenchmarkJSONMarshal benchmarks the JSON marshaling |
|
func BenchmarkJSONMarshal(b *testing.B) { |
|
ev := createTestEvent() |
|
defer ev.Free() |
|
|
|
b.ResetTimer() |
|
b.ReportAllocs() |
|
|
|
for i := 0; i < b.N; i++ { |
|
_ = ev.Marshal(nil) |
|
} |
|
} |
|
|
|
// BenchmarkJSONMarshalLarge benchmarks JSON marshaling with large events |
|
func BenchmarkJSONMarshalLarge(b *testing.B) { |
|
ev := createLargeTestEvent() |
|
defer ev.Free() |
|
|
|
b.ResetTimer() |
|
b.ReportAllocs() |
|
|
|
for i := 0; i < b.N; i++ { |
|
_ = ev.Marshal(nil) |
|
} |
|
} |
|
|
|
// BenchmarkJSONUnmarshal benchmarks JSON unmarshaling |
|
func BenchmarkJSONUnmarshal(b *testing.B) { |
|
ev := createTestEvent() |
|
jsonData := ev.Marshal(nil) |
|
defer ev.Free() |
|
|
|
b.ResetTimer() |
|
b.ReportAllocs() |
|
|
|
for i := 0; i < b.N; i++ { |
|
ev2 := New() |
|
_, err := ev2.Unmarshal(jsonData) |
|
if err != nil { |
|
b.Fatal(err) |
|
} |
|
ev2.Free() |
|
} |
|
} |
|
|
|
// BenchmarkBinaryMarshal benchmarks binary marshaling |
|
func BenchmarkBinaryMarshal(b *testing.B) { |
|
ev := createTestEvent() |
|
defer ev.Free() |
|
|
|
buf := &bytes.Buffer{} |
|
b.ResetTimer() |
|
b.ReportAllocs() |
|
|
|
for i := 0; i < b.N; i++ { |
|
buf.Reset() |
|
ev.MarshalBinary(buf) |
|
} |
|
} |
|
|
|
// BenchmarkBinaryMarshalLarge benchmarks binary marshaling with large events |
|
func BenchmarkBinaryMarshalLarge(b *testing.B) { |
|
ev := createLargeTestEvent() |
|
defer ev.Free() |
|
|
|
buf := &bytes.Buffer{} |
|
b.ResetTimer() |
|
b.ReportAllocs() |
|
|
|
for i := 0; i < b.N; i++ { |
|
buf.Reset() |
|
ev.MarshalBinary(buf) |
|
} |
|
} |
|
|
|
// BenchmarkBinaryUnmarshal benchmarks binary unmarshaling |
|
func BenchmarkBinaryUnmarshal(b *testing.B) { |
|
ev := createTestEvent() |
|
buf := &bytes.Buffer{} |
|
ev.MarshalBinary(buf) |
|
binaryData := buf.Bytes() |
|
defer ev.Free() |
|
|
|
b.ResetTimer() |
|
b.ReportAllocs() |
|
|
|
for i := 0; i < b.N; i++ { |
|
ev2 := New() |
|
reader := bytes.NewReader(binaryData) |
|
if err := ev2.UnmarshalBinary(reader); err != nil { |
|
b.Fatal(err) |
|
} |
|
ev2.Free() |
|
} |
|
} |
|
|
|
// BenchmarkCanonical benchmarks canonical encoding |
|
func BenchmarkCanonical(b *testing.B) { |
|
ev := createTestEvent() |
|
defer ev.Free() |
|
|
|
b.ResetTimer() |
|
b.ReportAllocs() |
|
|
|
for i := 0; i < b.N; i++ { |
|
_ = ev.ToCanonical(nil) |
|
} |
|
} |
|
|
|
// BenchmarkCanonicalLarge benchmarks canonical encoding with large events |
|
func BenchmarkCanonicalLarge(b *testing.B) { |
|
ev := createLargeTestEvent() |
|
defer ev.Free() |
|
|
|
b.ResetTimer() |
|
b.ReportAllocs() |
|
|
|
for i := 0; i < b.N; i++ { |
|
_ = ev.ToCanonical(nil) |
|
} |
|
} |
|
|
|
// BenchmarkGetIDBytes benchmarks ID generation (canonical + hash) |
|
func BenchmarkGetIDBytes(b *testing.B) { |
|
ev := createTestEvent() |
|
defer ev.Free() |
|
|
|
b.ResetTimer() |
|
b.ReportAllocs() |
|
|
|
for i := 0; i < b.N; i++ { |
|
_ = ev.GetIDBytes() |
|
} |
|
} |
|
|
|
// BenchmarkRoundTripJSON benchmarks JSON marshal/unmarshal round trip |
|
func BenchmarkRoundTripJSON(b *testing.B) { |
|
ev := createTestEvent() |
|
defer ev.Free() |
|
|
|
b.ResetTimer() |
|
b.ReportAllocs() |
|
|
|
for i := 0; i < b.N; i++ { |
|
jsonData := ev.Marshal(nil) |
|
ev2 := New() |
|
_, err := ev2.Unmarshal(jsonData) |
|
if err != nil { |
|
b.Fatal(err) |
|
} |
|
ev2.Free() |
|
} |
|
} |
|
|
|
// BenchmarkRoundTripBinary benchmarks binary marshal/unmarshal round trip |
|
func BenchmarkRoundTripBinary(b *testing.B) { |
|
ev := createTestEvent() |
|
defer ev.Free() |
|
|
|
buf := &bytes.Buffer{} |
|
b.ResetTimer() |
|
b.ReportAllocs() |
|
|
|
for i := 0; i < b.N; i++ { |
|
buf.Reset() |
|
ev.MarshalBinary(buf) |
|
|
|
ev2 := New() |
|
reader := bytes.NewReader(buf.Bytes()) |
|
if err := ev2.UnmarshalBinary(reader); err != nil { |
|
b.Fatal(err) |
|
} |
|
ev2.Free() |
|
} |
|
} |
|
|
|
// BenchmarkEstimateSize benchmarks size estimation |
|
func BenchmarkEstimateSize(b *testing.B) { |
|
ev := createTestEvent() |
|
defer ev.Free() |
|
|
|
b.ResetTimer() |
|
b.ReportAllocs() |
|
|
|
for i := 0; i < b.N; i++ { |
|
_ = ev.EstimateSize() |
|
} |
|
} |
|
|
|
|