From 4b7dfe1e7764d8424b1be935c7fea09a102382e8 Mon Sep 17 00:00:00 2001 From: bndw Date: Mon, 16 Feb 2026 10:58:11 -0800 Subject: fix: cleanup bench --- BENCHMARKS.md | 47 +-- BENCHMARK_SUMMARY.md | 2 +- benchmarks/comparison/README.md | 44 +++ benchmarks/comparison/comparison_bench_test.go | 510 ++++++++++++++++++++++++ benchmarks/comparison/go.mod | 39 ++ benchmarks/comparison/go.sum | 85 ++++ comparison_bench_test.go | 512 ------------------------- example_test.go | 2 +- examples/basic/main.go | 2 +- go.mod | 2 +- relay.go | 2 +- relay_test.go | 2 +- 12 files changed, 708 insertions(+), 541 deletions(-) create mode 100644 benchmarks/comparison/README.md create mode 100644 benchmarks/comparison/comparison_bench_test.go create mode 100644 benchmarks/comparison/go.mod create mode 100644 benchmarks/comparison/go.sum delete mode 100644 comparison_bench_test.go diff --git a/BENCHMARKS.md b/BENCHMARKS.md index 14a861c..1a671c1 100644 --- a/BENCHMARKS.md +++ b/BENCHMARKS.md @@ -2,7 +2,7 @@ This directory contains comprehensive benchmarks comparing three popular Go Nostr libraries: -- **NWIO** (`northwest.io/nostr`) - This library +- **NWIO** (`code.northwest.io/nostr`) - This library - **NBD** (`github.com/nbd-wtf/go-nostr`) - Popular community library - **Fiat** (`fiatjaf.com/nostr`) - Original implementation by Fiatjaf @@ -25,61 +25,60 @@ This directory contains comprehensive benchmarks comparing three popular Go Nost ## Running Benchmarks -**Important**: The comparison benchmarks require the `benchcmp` build tag to avoid polluting the module dependencies with competitor libraries. +**Important**: The comparison benchmarks are in a separate module (`benchmarks/comparison/`) to avoid polluting the main module dependencies with competitor libraries. ### Quick Start -Run all benchmarks (automatically handles dependencies): +Run all comparison benchmarks: ```bash -./run_benchmarks.sh -``` - -Or manually: -```bash -# First, get the comparison dependencies -go get -tags=benchcmp -t ./... - -# Then run the benchmarks -go test -tags=benchcmp -bench=. -benchmem -benchtime=1s +cd benchmarks/comparison +go test -bench=. -benchmem -benchtime=1s ``` ### Specific Benchmark Groups Event unmarshaling: ```bash -go test -tags=benchcmp -bench=BenchmarkEventUnmarshal -benchmem +cd benchmarks/comparison +go test -bench=BenchmarkEventUnmarshal -benchmem ``` Event signing: ```bash -go test -tags=benchcmp -bench=BenchmarkEventSign -benchmem +cd benchmarks/comparison +go test -bench=BenchmarkEventSign -benchmem ``` Event verification: ```bash -go test -tags=benchcmp -bench=BenchmarkEventVerify -benchmem +cd benchmarks/comparison +go test -bench=BenchmarkEventVerify -benchmem ``` Filter matching: ```bash -go test -tags=benchcmp -bench=BenchmarkFilterMatch -benchmem +cd benchmarks/comparison +go test -bench=BenchmarkFilterMatch -benchmem ``` ### Compare Single Library NWIO only: ```bash -go test -tags=benchcmp -bench='.*_NWIO' -benchmem +cd benchmarks/comparison +go test -bench='.*_NWIO' -benchmem ``` NBD only: ```bash -go test -tags=benchcmp -bench='.*_NBD' -benchmem +cd benchmarks/comparison +go test -bench='.*_NBD' -benchmem ``` Fiat only: ```bash -go test -tags=benchcmp -bench='.*_Fiat' -benchmem +cd benchmarks/comparison +go test -bench='.*_Fiat' -benchmem ``` ## Analyzing Results @@ -91,14 +90,16 @@ Use `benchstat` for statistical analysis: go install golang.org/x/perf/cmd/benchstat@latest # Run benchmarks multiple times and compare -go test -tags=benchcmp -bench=. -benchmem -count=10 > results.txt +cd benchmarks/comparison +go test -bench=. -benchmem -count=10 > results.txt benchstat results.txt ``` Compare two specific libraries: ```bash -go test -tags=benchcmp -bench='.*_NWIO' -benchmem -count=10 > nwio.txt -go test -tags=benchcmp -bench='.*_NBD' -benchmem -count=10 > nbd.txt +cd benchmarks/comparison +go test -bench='.*_NWIO' -benchmem -count=10 > nwio.txt +go test -bench='.*_NBD' -benchmem -count=10 > nbd.txt benchstat nwio.txt nbd.txt ``` diff --git a/BENCHMARK_SUMMARY.md b/BENCHMARK_SUMMARY.md index e7f5b6d..2e087a3 100644 --- a/BENCHMARK_SUMMARY.md +++ b/BENCHMARK_SUMMARY.md @@ -1,6 +1,6 @@ # Benchmark Results Summary -Comparison of three Go Nostr libraries: **NWIO** (northwest.io/nostr), **NBD** (github.com/nbd-wtf/go-nostr), and **Fiat** (fiatjaf.com/nostr) +Comparison of three Go Nostr libraries: **NWIO** (code.northwest.io/nostr), **NBD** (github.com/nbd-wtf/go-nostr), and **Fiat** (fiatjaf.com/nostr) ## Quick Performance Overview diff --git a/benchmarks/comparison/README.md b/benchmarks/comparison/README.md new file mode 100644 index 0000000..1b97429 --- /dev/null +++ b/benchmarks/comparison/README.md @@ -0,0 +1,44 @@ +# Nostr Library Comparison Benchmarks + +This module contains benchmarks comparing `code.northwest.io/nostr` with other popular Go Nostr libraries: + +- **NWIO** (`code.northwest.io/nostr`) - This library +- **NBD** (`github.com/nbd-wtf/go-nostr`) - Popular community library +- **Fiat** (`fiatjaf.com/nostr`) - Original implementation by Fiatjaf + +## Why a Separate Module? + +The comparison libraries are isolated in this separate Go module to keep the main `code.northwest.io/nostr` package clean. Users who import the main package won't have `fiatjaf.com/nostr` or `github.com/nbd-wtf/go-nostr` pulled into their dependency tree. + +## Running Benchmarks + +From this directory: + +```bash +# Run all comparison benchmarks +go test -bench=. -benchmem + +# Run specific benchmarks +go test -bench=BenchmarkEventSign -benchmem + +# Compare NWIO vs NBD +go test -bench='.*_(NWIO|NBD)' -benchmem +``` + +From the project root: + +```bash +cd benchmarks/comparison +go test -bench=. -benchmem +``` + +## Benchmark Categories + +- **Event Unmarshaling/Marshaling**: JSON parsing and serialization +- **Event Serialization**: Canonical serialization for ID computation +- **Event ID Computation**: Computing event ID hashes +- **Key Generation**: Generating new private keys +- **Event Signing/Verification**: Cryptographic operations +- **Filter Matching**: Simple and complex filter matching + +See [../../BENCHMARKS.md](../../BENCHMARKS.md) for detailed documentation. diff --git a/benchmarks/comparison/comparison_bench_test.go b/benchmarks/comparison/comparison_bench_test.go new file mode 100644 index 0000000..866b4df --- /dev/null +++ b/benchmarks/comparison/comparison_bench_test.go @@ -0,0 +1,510 @@ +package comparison_test + +import ( + "encoding/hex" + "encoding/json" + "testing" + + nwio "code.northwest.io/nostr" + nbd "github.com/nbd-wtf/go-nostr" + fiat "fiatjaf.com/nostr" +) + +// Sample event data for benchmarks +var ( + samplePubKey = "3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d" + sampleSig = "230e9d8f0ddaf7eb70b5f7741ccfa37e87a455c9a469282e3464e2052d3192cd63a167e196e381ef9d7e69e9ea43af2b0d0e1b8f1e6e7c4e1c6e8e3e9e8e3e9e8" + sampleID = "d42c96ccac39e0113b2ef8df82e82e2e15e0e1e7e9e5e7e1e7e9e5e7e1e7e9e5" + + sampleEventJSON = `{ + "id": "d42c96ccac39e0113b2ef8df82e82e2e15e0e1e7e9e5e7e1e7e9e5e7e1e7e9e5", + "pubkey": "3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d", + "created_at": 1672531200, + "kind": 1, + "tags": [["e", "5c83da77af1dec6d7289834998ad7aafbd9e2191396d75ec3cc27f5a77226f36", "wss://nostr.example.com"]], + "content": "Hello Nostr!", + "sig": "230e9d8f0ddaf7eb70b5f7741ccfa37e87a455c9a469282e3464e2052d3192cd63a167e196e381ef9d7e69e9ea43af2b0d0e1b8f1e6e7c4e1c6e8e3e9e8e3e9e8" + }` +) + +// ============================================================================ +// Event Unmarshaling Benchmarks +// ============================================================================ + +func BenchmarkEventUnmarshal_NWIO(b *testing.B) { + data := []byte(sampleEventJSON) + b.ResetTimer() + for i := 0; i < b.N; i++ { + var evt nwio.Event + if err := json.Unmarshal(data, &evt); err != nil { + b.Fatal(err) + } + } +} + +func BenchmarkEventUnmarshal_NBD(b *testing.B) { + data := []byte(sampleEventJSON) + b.ResetTimer() + for i := 0; i < b.N; i++ { + var evt nbd.Event + if err := json.Unmarshal(data, &evt); err != nil { + b.Fatal(err) + } + } +} + +func BenchmarkEventUnmarshal_Fiat(b *testing.B) { + data := []byte(sampleEventJSON) + b.ResetTimer() + for i := 0; i < b.N; i++ { + var evt fiat.Event + if err := json.Unmarshal(data, &evt); err != nil { + b.Fatal(err) + } + } +} + +// ============================================================================ +// Event Marshaling Benchmarks +// ============================================================================ + +func BenchmarkEventMarshal_NWIO(b *testing.B) { + evt := &nwio.Event{ + ID: sampleID, + PubKey: samplePubKey, + CreatedAt: 1672531200, + Kind: 1, + Tags: nwio.Tags{{"e", "5c83da77af1dec6d7289834998ad7aafbd9e2191396d75ec3cc27f5a77226f36"}}, + Content: "Hello Nostr!", + Sig: sampleSig, + } + b.ResetTimer() + for i := 0; i < b.N; i++ { + if _, err := json.Marshal(evt); err != nil { + b.Fatal(err) + } + } +} + +func BenchmarkEventMarshal_NBD(b *testing.B) { + evt := &nbd.Event{ + ID: sampleID, + PubKey: samplePubKey, + CreatedAt: nbd.Timestamp(1672531200), + Kind: 1, + Tags: nbd.Tags{{"e", "5c83da77af1dec6d7289834998ad7aafbd9e2191396d75ec3cc27f5a77226f36"}}, + Content: "Hello Nostr!", + Sig: sampleSig, + } + b.ResetTimer() + for i := 0; i < b.N; i++ { + if _, err := json.Marshal(evt); err != nil { + b.Fatal(err) + } + } +} + +func BenchmarkEventMarshal_Fiat(b *testing.B) { + sig, _ := hex.DecodeString(sampleSig) + var sigBytes [64]byte + copy(sigBytes[:], sig) + + pubkey, _ := fiat.PubKeyFromHex(samplePubKey) + id, _ := fiat.IDFromHex(sampleID) + + evt := &fiat.Event{ + ID: id, + PubKey: pubkey, + CreatedAt: fiat.Timestamp(1672531200), + Kind: 1, + Tags: fiat.Tags{{"e", "5c83da77af1dec6d7289834998ad7aafbd9e2191396d75ec3cc27f5a77226f36"}}, + Content: "Hello Nostr!", + Sig: sigBytes, + } + b.ResetTimer() + for i := 0; i < b.N; i++ { + if _, err := json.Marshal(evt); err != nil { + b.Fatal(err) + } + } +} + +// ============================================================================ +// Event Serialization (for ID computation) Benchmarks +// ============================================================================ + +func BenchmarkEventSerialize_NWIO(b *testing.B) { + evt := &nwio.Event{ + PubKey: samplePubKey, + CreatedAt: 1672531200, + Kind: 1, + Tags: nwio.Tags{{"e", "5c83da77af1dec6d7289834998ad7aafbd9e2191396d75ec3cc27f5a77226f36"}}, + Content: "Hello Nostr!", + } + b.ResetTimer() + for i := 0; i < b.N; i++ { + _ = evt.Serialize() + } +} + +func BenchmarkEventSerialize_NBD(b *testing.B) { + evt := &nbd.Event{ + PubKey: samplePubKey, + CreatedAt: nbd.Timestamp(1672531200), + Kind: 1, + Tags: nbd.Tags{{"e", "5c83da77af1dec6d7289834998ad7aafbd9e2191396d75ec3cc27f5a77226f36"}}, + Content: "Hello Nostr!", + } + b.ResetTimer() + for i := 0; i < b.N; i++ { + _ = evt.Serialize() + } +} + +func BenchmarkEventSerialize_Fiat(b *testing.B) { + pubkey, _ := fiat.PubKeyFromHex(samplePubKey) + evt := &fiat.Event{ + PubKey: pubkey, + CreatedAt: fiat.Timestamp(1672531200), + Kind: 1, + Tags: fiat.Tags{{"e", "5c83da77af1dec6d7289834998ad7aafbd9e2191396d75ec3cc27f5a77226f36"}}, + Content: "Hello Nostr!", + } + b.ResetTimer() + for i := 0; i < b.N; i++ { + _ = evt.Serialize() + } +} + +// ============================================================================ +// Event ID Computation Benchmarks +// ============================================================================ + +func BenchmarkComputeID_NWIO(b *testing.B) { + evt := &nwio.Event{ + PubKey: samplePubKey, + CreatedAt: 1672531200, + Kind: 1, + Tags: nwio.Tags{{"e", "5c83da77af1dec6d7289834998ad7aafbd9e2191396d75ec3cc27f5a77226f36"}}, + Content: "Hello Nostr!", + } + b.ResetTimer() + for i := 0; i < b.N; i++ { + _ = evt.ComputeID() + } +} + +func BenchmarkComputeID_NBD(b *testing.B) { + evt := &nbd.Event{ + PubKey: samplePubKey, + CreatedAt: nbd.Timestamp(1672531200), + Kind: 1, + Tags: nbd.Tags{{"e", "5c83da77af1dec6d7289834998ad7aafbd9e2191396d75ec3cc27f5a77226f36"}}, + Content: "Hello Nostr!", + } + b.ResetTimer() + for i := 0; i < b.N; i++ { + _ = evt.GetID() + } +} + +func BenchmarkComputeID_Fiat(b *testing.B) { + pubkey, _ := fiat.PubKeyFromHex(samplePubKey) + evt := &fiat.Event{ + PubKey: pubkey, + CreatedAt: fiat.Timestamp(1672531200), + Kind: 1, + Tags: fiat.Tags{{"e", "5c83da77af1dec6d7289834998ad7aafbd9e2191396d75ec3cc27f5a77226f36"}}, + Content: "Hello Nostr!", + } + b.ResetTimer() + for i := 0; i < b.N; i++ { + _ = evt.GetID() + } +} + +// ============================================================================ +// Key Generation Benchmarks +// ============================================================================ + +func BenchmarkGenerateKey_NWIO(b *testing.B) { + for i := 0; i < b.N; i++ { + if _, err := nwio.GenerateKey(); err != nil { + b.Fatal(err) + } + } +} + +func BenchmarkGenerateKey_NBD(b *testing.B) { + for i := 0; i < b.N; i++ { + _ = nbd.GeneratePrivateKey() + } +} + +func BenchmarkGenerateKey_Fiat(b *testing.B) { + for i := 0; i < b.N; i++ { + _ = fiat.Generate() + } +} + +// ============================================================================ +// Event Signing Benchmarks +// ============================================================================ + +func BenchmarkEventSign_NWIO(b *testing.B) { + key, err := nwio.GenerateKey() + if err != nil { + b.Fatal(err) + } + b.ResetTimer() + + for i := 0; i < b.N; i++ { + evt := &nwio.Event{ + CreatedAt: 1672531200, + Kind: 1, + Tags: nwio.Tags{}, + Content: "Hello Nostr!", + } + if err := key.Sign(evt); err != nil { + b.Fatal(err) + } + } +} + +func BenchmarkEventSign_NBD(b *testing.B) { + sk := nbd.GeneratePrivateKey() + b.ResetTimer() + + for i := 0; i < b.N; i++ { + evt := &nbd.Event{ + CreatedAt: nbd.Timestamp(1672531200), + Kind: 1, + Tags: nbd.Tags{}, + Content: "Hello Nostr!", + } + if err := evt.Sign(sk); err != nil { + b.Fatal(err) + } + } +} + +func BenchmarkEventSign_Fiat(b *testing.B) { + sk := fiat.Generate() + b.ResetTimer() + + for i := 0; i < b.N; i++ { + evt := &fiat.Event{ + CreatedAt: fiat.Timestamp(1672531200), + Kind: 1, + Tags: fiat.Tags{}, + Content: "Hello Nostr!", + } + if err := evt.Sign(sk); err != nil { + b.Fatal(err) + } + } +} + +// ============================================================================ +// Event Verification Benchmarks +// ============================================================================ + +func BenchmarkEventVerify_NWIO(b *testing.B) { + // Create and sign an event + key, _ := nwio.GenerateKey() + evt := &nwio.Event{ + CreatedAt: 1672531200, + Kind: 1, + Tags: nwio.Tags{}, + Content: "Hello Nostr!", + } + key.Sign(evt) + + b.ResetTimer() + for i := 0; i < b.N; i++ { + if !evt.Verify() { + b.Fatal("verification failed") + } + } +} + +func BenchmarkEventVerify_NBD(b *testing.B) { + // Create and sign an event + sk := nbd.GeneratePrivateKey() + evt := &nbd.Event{ + CreatedAt: nbd.Timestamp(1672531200), + Kind: 1, + Tags: nbd.Tags{}, + Content: "Hello Nostr!", + } + evt.Sign(sk) + + b.ResetTimer() + for i := 0; i < b.N; i++ { + if ok, _ := evt.CheckSignature(); !ok { + b.Fatal("verification failed") + } + } +} + +func BenchmarkEventVerify_Fiat(b *testing.B) { + // Create and sign an event + sk := fiat.Generate() + evt := &fiat.Event{ + CreatedAt: fiat.Timestamp(1672531200), + Kind: 1, + Tags: fiat.Tags{}, + Content: "Hello Nostr!", + } + evt.Sign(sk) + + b.ResetTimer() + for i := 0; i < b.N; i++ { + if !evt.VerifySignature() { + b.Fatal("verification failed") + } + } +} + +// ============================================================================ +// Filter Matching Benchmarks +// ============================================================================ + +func BenchmarkFilterMatch_NWIO(b *testing.B) { + filter := &nwio.Filter{ + Kinds: []int{1}, + Authors: []string{samplePubKey}, + } + evt := &nwio.Event{ + PubKey: samplePubKey, + CreatedAt: 1672531200, + Kind: 1, + Content: "Hello Nostr!", + } + + b.ResetTimer() + for i := 0; i < b.N; i++ { + if !filter.Matches(evt) { + b.Fatal("filter should match") + } + } +} + +func BenchmarkFilterMatch_NBD(b *testing.B) { + filter := nbd.Filter{ + Kinds: []int{1}, + Authors: []string{samplePubKey}, + } + evt := &nbd.Event{ + PubKey: samplePubKey, + CreatedAt: nbd.Timestamp(1672531200), + Kind: 1, + Content: "Hello Nostr!", + } + + b.ResetTimer() + for i := 0; i < b.N; i++ { + if !filter.Matches(evt) { + b.Fatal("filter should match") + } + } +} + +func BenchmarkFilterMatch_Fiat(b *testing.B) { + pubkey, _ := fiat.PubKeyFromHex(samplePubKey) + filter := fiat.Filter{ + Kinds: []fiat.Kind{1}, + Authors: []fiat.PubKey{pubkey}, + } + evt := &fiat.Event{ + PubKey: pubkey, + CreatedAt: fiat.Timestamp(1672531200), + Kind: 1, + Content: "Hello Nostr!", + } + + b.ResetTimer() + for i := 0; i < b.N; i++ { + if !filter.Matches(*evt) { + b.Fatal("filter should match") + } + } +} + +// ============================================================================ +// Complex Filter Matching Benchmarks (with tags) +// ============================================================================ + +func BenchmarkFilterMatchComplex_NWIO(b *testing.B) { + filter := &nwio.Filter{ + Kinds: []int{1, 6, 7}, + Authors: []string{samplePubKey[:8]}, // Prefix match + Tags: map[string][]string{ + "e": {"5c83da77af1dec6d7289834998ad7aafbd9e2191396d75ec3cc27f5a77226f36"}, + }, + } + evt := &nwio.Event{ + PubKey: samplePubKey, + CreatedAt: 1672531200, + Kind: 1, + Tags: nwio.Tags{{"e", "5c83da77af1dec6d7289834998ad7aafbd9e2191396d75ec3cc27f5a77226f36"}}, + Content: "Hello Nostr!", + } + + b.ResetTimer() + for i := 0; i < b.N; i++ { + if !filter.Matches(evt) { + b.Fatal("filter should match") + } + } +} + +func BenchmarkFilterMatchComplex_NBD(b *testing.B) { + filter := nbd.Filter{ + Kinds: []int{1, 6, 7}, + Authors: []string{samplePubKey}, // NBD also supports prefix, use full key for simplicity + Tags: nbd.TagMap{ + "e": []string{"5c83da77af1dec6d7289834998ad7aafbd9e2191396d75ec3cc27f5a77226f36"}, + }, + } + evt := &nbd.Event{ + PubKey: samplePubKey, + CreatedAt: nbd.Timestamp(1672531200), + Kind: 1, + Tags: nbd.Tags{{"e", "5c83da77af1dec6d7289834998ad7aafbd9e2191396d75ec3cc27f5a77226f36"}}, + Content: "Hello Nostr!", + } + + b.ResetTimer() + for i := 0; i < b.N; i++ { + if !filter.Matches(evt) { + b.Fatal("filter should match") + } + } +} + +func BenchmarkFilterMatchComplex_Fiat(b *testing.B) { + pubkey, _ := fiat.PubKeyFromHex(samplePubKey) + + filter := fiat.Filter{ + Kinds: []fiat.Kind{1, 6, 7}, + Authors: []fiat.PubKey{pubkey}, // Use full pubkey for simplicity + Tags: fiat.TagMap{ + "e": []string{"5c83da77af1dec6d7289834998ad7aafbd9e2191396d75ec3cc27f5a77226f36"}, + }, + } + evt := &fiat.Event{ + PubKey: pubkey, + CreatedAt: fiat.Timestamp(1672531200), + Kind: 1, + Tags: fiat.Tags{{"e", "5c83da77af1dec6d7289834998ad7aafbd9e2191396d75ec3cc27f5a77226f36"}}, + Content: "Hello Nostr!", + } + + b.ResetTimer() + for i := 0; i < b.N; i++ { + if !filter.Matches(*evt) { + b.Fatal("filter should match") + } + } +} diff --git a/benchmarks/comparison/go.mod b/benchmarks/comparison/go.mod new file mode 100644 index 0000000..f76c374 --- /dev/null +++ b/benchmarks/comparison/go.mod @@ -0,0 +1,39 @@ +module code.northwest.io/nostr/benchmarks/comparison + +go 1.25 + +require ( + code.northwest.io/nostr v0.0.0 + fiatjaf.com/nostr v0.0.0-20260211144128-7a4b71b39b12 + github.com/nbd-wtf/go-nostr v0.52.3 +) + +require ( + github.com/ImVexed/fasturl v0.0.0-20230304231329-4e41488060f3 // indirect + github.com/btcsuite/btcd/btcec/v2 v2.3.4 // indirect + github.com/btcsuite/btcd/chaincfg/chainhash v1.1.0 // indirect + github.com/bytedance/sonic v1.13.1 // indirect + github.com/bytedance/sonic/loader v0.2.4 // indirect + github.com/cloudwego/base64x v0.1.5 // indirect + github.com/coder/websocket v1.8.13 // indirect + github.com/decred/dcrd/crypto/blake256 v1.1.0 // indirect + github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0 // indirect + github.com/josharian/intern v1.0.0 // indirect + github.com/json-iterator/go v1.1.12 // indirect + github.com/klauspost/cpuid/v2 v2.2.10 // indirect + github.com/mailru/easyjson v0.9.0 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/puzpuzpuz/xsync/v3 v3.5.1 // indirect + github.com/templexxx/cpu v0.0.1 // indirect + github.com/templexxx/xhex v0.0.0-20200614015412-aed53437177b // indirect + github.com/tidwall/gjson v1.18.0 // indirect + github.com/tidwall/match v1.1.1 // indirect + github.com/tidwall/pretty v1.2.1 // indirect + github.com/twitchyliquid64/golang-asm v0.15.1 // indirect + golang.org/x/arch v0.15.0 // indirect + golang.org/x/exp v0.0.0-20250305212735-054e65f0b394 // indirect + golang.org/x/sys v0.35.0 // indirect +) + +replace code.northwest.io/nostr => ../.. diff --git a/benchmarks/comparison/go.sum b/benchmarks/comparison/go.sum new file mode 100644 index 0000000..fb3bb78 --- /dev/null +++ b/benchmarks/comparison/go.sum @@ -0,0 +1,85 @@ +fiatjaf.com/nostr v0.0.0-20260211144128-7a4b71b39b12 h1:lNVaw/O5ThXVzO0Pz7D+b9fys/OaVaDG3C10kCJQFvg= +fiatjaf.com/nostr v0.0.0-20260211144128-7a4b71b39b12/go.mod h1:ue7yw0zHfZj23Ml2kVSdBx0ENEaZiuvGxs/8VEN93FU= +github.com/ImVexed/fasturl v0.0.0-20230304231329-4e41488060f3 h1:ClzzXMDDuUbWfNNZqGeYq4PnYOlwlOVIvSyNaIy0ykg= +github.com/ImVexed/fasturl v0.0.0-20230304231329-4e41488060f3/go.mod h1:we0YA5CsBbH5+/NUzC/AlMmxaDtWlXeNsqrwXjTzmzA= +github.com/btcsuite/btcd/btcec/v2 v2.3.4 h1:3EJjcN70HCu/mwqlUsGK8GcNVyLVxFDlWurTXGPFfiQ= +github.com/btcsuite/btcd/btcec/v2 v2.3.4/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04= +github.com/btcsuite/btcd/chaincfg/chainhash v1.1.0 h1:59Kx4K6lzOW5w6nFlA0v5+lk/6sjybR934QNHSJZPTQ= +github.com/btcsuite/btcd/chaincfg/chainhash v1.1.0/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc= +github.com/bytedance/sonic v1.13.1 h1:Jyd5CIvdFnkOWuKXr+wm4Nyk2h0yAFsr8ucJgEasO3g= +github.com/bytedance/sonic v1.13.1/go.mod h1:o68xyaF9u2gvVBuGHPlUVCy+ZfmNNO5ETf1+KgkJhz4= +github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= +github.com/bytedance/sonic/loader v0.2.4 h1:ZWCw4stuXUsn1/+zQDqeE7JKP+QO47tz7QCNan80NzY= +github.com/bytedance/sonic/loader v0.2.4/go.mod h1:N8A3vUdtUebEY2/VQC0MyhYeKUFosQU6FxH2JmUe6VI= +github.com/cloudwego/base64x v0.1.5 h1:XPciSp1xaq2VCSt6lF0phncD4koWyULpl5bUxbfCyP4= +github.com/cloudwego/base64x v0.1.5/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w= +github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY= +github.com/coder/websocket v1.8.13 h1:f3QZdXy7uGVz+4uCJy2nTZyM0yTBj8yANEHhqlXZ9FE= +github.com/coder/websocket v1.8.13/go.mod h1:LNVeNrXQZfe5qhS9ALED3uA+l5pPqvwXg3CKoDBB2gs= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/decred/dcrd/crypto/blake256 v1.1.0 h1:zPMNGQCm0g4QTY27fOCorQW7EryeQ/U0x++OzVrdms8= +github.com/decred/dcrd/crypto/blake256 v1.1.0/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0 h1:NMZiJj8QnKe1LgsbDayM4UoHwbvwDRwnI3hwNaAHRnc= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0/go.mod h1:ZXNYxsqcloTdSy/rNShjYzMhyjf0LaoftYK0p+A3h40= +github.com/dvyukov/go-fuzz v0.0.0-20200318091601-be3528f3a813/go.mod h1:11Gm+ccJnvAhCNLlf5+cS9KjtbaD5I5zaZpFMsTHWTw= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= +github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= +github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= +github.com/klauspost/cpuid/v2 v2.2.10 h1:tBs3QSyvjDyFTq3uoc/9xFpCuOsJQFNPiAhYdw2skhE= +github.com/klauspost/cpuid/v2 v2.2.10/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0= +github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M= +github.com/mailru/easyjson v0.9.0 h1:PrnmzHw7262yW8sTBwxi1PdJA3Iw/EKBa8psRf7d9a4= +github.com/mailru/easyjson v0.9.0/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/nbd-wtf/go-nostr v0.52.3 h1:Xd87pXfJEJRXHpM+fLjQQln8dBNNaoPA10V7BbyP4KI= +github.com/nbd-wtf/go-nostr v0.52.3/go.mod h1:4avYoc9mDGZ9wHsvCOhHH9vPzKucCfuYBtJUSpHTfNk= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/puzpuzpuz/xsync/v3 v3.5.1 h1:GJYJZwO6IdxN/IKbneznS6yPkVC+c3zyY/j19c++5Fg= +github.com/puzpuzpuz/xsync/v3 v3.5.1/go.mod h1:VjzYrABPabuM4KyBh1Ftq6u8nhwY5tBPKP9jpmh0nnA= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/templexxx/cpu v0.0.1 h1:hY4WdLOgKdc8y13EYklu9OUTXik80BkxHoWvTO6MQQY= +github.com/templexxx/cpu v0.0.1/go.mod h1:w7Tb+7qgcAlIyX4NhLuDKt78AHA5SzPmq0Wj6HiEnnk= +github.com/templexxx/xhex v0.0.0-20200614015412-aed53437177b h1:XeDLE6c9mzHpdv3Wb1+pWBaWv/BlHK0ZYIu/KaL6eHg= +github.com/templexxx/xhex v0.0.0-20200614015412-aed53437177b/go.mod h1:7rwmCH0wC2fQvNEvPZ3sKXukhyCTyiaZ5VTZMQYpZKQ= +github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY= +github.com/tidwall/gjson v1.18.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= +github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= +github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= +github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= +github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4= +github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= +github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= +github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= +golang.org/x/arch v0.15.0 h1:QtOrQd0bTUnhNVNndMpLHNWrDmYzZ2KDqSrEymqInZw= +golang.org/x/arch v0.15.0/go.mod h1:JmwW7aLIoRUKgaTzhkiEFxvcEiQGyOg9BMonBJUS7EE= +golang.org/x/exp v0.0.0-20250305212735-054e65f0b394 h1:nDVHiLt8aIbd/VzvPWN6kSOPE7+F/fNFDSXLVYkE/Iw= +golang.org/x/exp v0.0.0-20250305212735-054e65f0b394/go.mod h1:sIifuuw/Yco/y6yb6+bDNfyeQ/MdPUy/hKEMYQV17cM= +golang.org/x/net v0.41.0 h1:vBTly1HeNPEn3wtREYfy4GZ/NECgw2Cnl+nK6Nz3uvw= +golang.org/x/net v0.41.0/go.mod h1:B/K4NNqkfmg07DQYrbwvSluqCJOOXwUjeb/5lOisjbA= +golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI= +golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50= diff --git a/comparison_bench_test.go b/comparison_bench_test.go deleted file mode 100644 index ee3e936..0000000 --- a/comparison_bench_test.go +++ /dev/null @@ -1,512 +0,0 @@ -//go:build benchcmp - -package nostr_test - -import ( - "encoding/hex" - "encoding/json" - "testing" - - nwio "northwest.io/nostr" - nbd "github.com/nbd-wtf/go-nostr" - fiat "fiatjaf.com/nostr" -) - -// Sample event data for benchmarks -var ( - samplePubKey = "3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d" - sampleSig = "230e9d8f0ddaf7eb70b5f7741ccfa37e87a455c9a469282e3464e2052d3192cd63a167e196e381ef9d7e69e9ea43af2b0d0e1b8f1e6e7c4e1c6e8e3e9e8e3e9e8" - sampleID = "d42c96ccac39e0113b2ef8df82e82e2e15e0e1e7e9e5e7e1e7e9e5e7e1e7e9e5" - - sampleEventJSON = `{ - "id": "d42c96ccac39e0113b2ef8df82e82e2e15e0e1e7e9e5e7e1e7e9e5e7e1e7e9e5", - "pubkey": "3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d", - "created_at": 1672531200, - "kind": 1, - "tags": [["e", "5c83da77af1dec6d7289834998ad7aafbd9e2191396d75ec3cc27f5a77226f36", "wss://nostr.example.com"]], - "content": "Hello Nostr!", - "sig": "230e9d8f0ddaf7eb70b5f7741ccfa37e87a455c9a469282e3464e2052d3192cd63a167e196e381ef9d7e69e9ea43af2b0d0e1b8f1e6e7c4e1c6e8e3e9e8e3e9e8" - }` -) - -// ============================================================================ -// Event Unmarshaling Benchmarks -// ============================================================================ - -func BenchmarkEventUnmarshal_NWIO(b *testing.B) { - data := []byte(sampleEventJSON) - b.ResetTimer() - for i := 0; i < b.N; i++ { - var evt nwio.Event - if err := json.Unmarshal(data, &evt); err != nil { - b.Fatal(err) - } - } -} - -func BenchmarkEventUnmarshal_NBD(b *testing.B) { - data := []byte(sampleEventJSON) - b.ResetTimer() - for i := 0; i < b.N; i++ { - var evt nbd.Event - if err := json.Unmarshal(data, &evt); err != nil { - b.Fatal(err) - } - } -} - -func BenchmarkEventUnmarshal_Fiat(b *testing.B) { - data := []byte(sampleEventJSON) - b.ResetTimer() - for i := 0; i < b.N; i++ { - var evt fiat.Event - if err := json.Unmarshal(data, &evt); err != nil { - b.Fatal(err) - } - } -} - -// ============================================================================ -// Event Marshaling Benchmarks -// ============================================================================ - -func BenchmarkEventMarshal_NWIO(b *testing.B) { - evt := &nwio.Event{ - ID: sampleID, - PubKey: samplePubKey, - CreatedAt: 1672531200, - Kind: 1, - Tags: nwio.Tags{{"e", "5c83da77af1dec6d7289834998ad7aafbd9e2191396d75ec3cc27f5a77226f36"}}, - Content: "Hello Nostr!", - Sig: sampleSig, - } - b.ResetTimer() - for i := 0; i < b.N; i++ { - if _, err := json.Marshal(evt); err != nil { - b.Fatal(err) - } - } -} - -func BenchmarkEventMarshal_NBD(b *testing.B) { - evt := &nbd.Event{ - ID: sampleID, - PubKey: samplePubKey, - CreatedAt: nbd.Timestamp(1672531200), - Kind: 1, - Tags: nbd.Tags{{"e", "5c83da77af1dec6d7289834998ad7aafbd9e2191396d75ec3cc27f5a77226f36"}}, - Content: "Hello Nostr!", - Sig: sampleSig, - } - b.ResetTimer() - for i := 0; i < b.N; i++ { - if _, err := json.Marshal(evt); err != nil { - b.Fatal(err) - } - } -} - -func BenchmarkEventMarshal_Fiat(b *testing.B) { - sig, _ := hex.DecodeString(sampleSig) - var sigBytes [64]byte - copy(sigBytes[:], sig) - - pubkey, _ := fiat.PubKeyFromHex(samplePubKey) - id, _ := fiat.IDFromHex(sampleID) - - evt := &fiat.Event{ - ID: id, - PubKey: pubkey, - CreatedAt: fiat.Timestamp(1672531200), - Kind: 1, - Tags: fiat.Tags{{"e", "5c83da77af1dec6d7289834998ad7aafbd9e2191396d75ec3cc27f5a77226f36"}}, - Content: "Hello Nostr!", - Sig: sigBytes, - } - b.ResetTimer() - for i := 0; i < b.N; i++ { - if _, err := json.Marshal(evt); err != nil { - b.Fatal(err) - } - } -} - -// ============================================================================ -// Event Serialization (for ID computation) Benchmarks -// ============================================================================ - -func BenchmarkEventSerialize_NWIO(b *testing.B) { - evt := &nwio.Event{ - PubKey: samplePubKey, - CreatedAt: 1672531200, - Kind: 1, - Tags: nwio.Tags{{"e", "5c83da77af1dec6d7289834998ad7aafbd9e2191396d75ec3cc27f5a77226f36"}}, - Content: "Hello Nostr!", - } - b.ResetTimer() - for i := 0; i < b.N; i++ { - _ = evt.Serialize() - } -} - -func BenchmarkEventSerialize_NBD(b *testing.B) { - evt := &nbd.Event{ - PubKey: samplePubKey, - CreatedAt: nbd.Timestamp(1672531200), - Kind: 1, - Tags: nbd.Tags{{"e", "5c83da77af1dec6d7289834998ad7aafbd9e2191396d75ec3cc27f5a77226f36"}}, - Content: "Hello Nostr!", - } - b.ResetTimer() - for i := 0; i < b.N; i++ { - _ = evt.Serialize() - } -} - -func BenchmarkEventSerialize_Fiat(b *testing.B) { - pubkey, _ := fiat.PubKeyFromHex(samplePubKey) - evt := &fiat.Event{ - PubKey: pubkey, - CreatedAt: fiat.Timestamp(1672531200), - Kind: 1, - Tags: fiat.Tags{{"e", "5c83da77af1dec6d7289834998ad7aafbd9e2191396d75ec3cc27f5a77226f36"}}, - Content: "Hello Nostr!", - } - b.ResetTimer() - for i := 0; i < b.N; i++ { - _ = evt.Serialize() - } -} - -// ============================================================================ -// Event ID Computation Benchmarks -// ============================================================================ - -func BenchmarkComputeID_NWIO(b *testing.B) { - evt := &nwio.Event{ - PubKey: samplePubKey, - CreatedAt: 1672531200, - Kind: 1, - Tags: nwio.Tags{{"e", "5c83da77af1dec6d7289834998ad7aafbd9e2191396d75ec3cc27f5a77226f36"}}, - Content: "Hello Nostr!", - } - b.ResetTimer() - for i := 0; i < b.N; i++ { - _ = evt.ComputeID() - } -} - -func BenchmarkComputeID_NBD(b *testing.B) { - evt := &nbd.Event{ - PubKey: samplePubKey, - CreatedAt: nbd.Timestamp(1672531200), - Kind: 1, - Tags: nbd.Tags{{"e", "5c83da77af1dec6d7289834998ad7aafbd9e2191396d75ec3cc27f5a77226f36"}}, - Content: "Hello Nostr!", - } - b.ResetTimer() - for i := 0; i < b.N; i++ { - _ = evt.GetID() - } -} - -func BenchmarkComputeID_Fiat(b *testing.B) { - pubkey, _ := fiat.PubKeyFromHex(samplePubKey) - evt := &fiat.Event{ - PubKey: pubkey, - CreatedAt: fiat.Timestamp(1672531200), - Kind: 1, - Tags: fiat.Tags{{"e", "5c83da77af1dec6d7289834998ad7aafbd9e2191396d75ec3cc27f5a77226f36"}}, - Content: "Hello Nostr!", - } - b.ResetTimer() - for i := 0; i < b.N; i++ { - _ = evt.GetID() - } -} - -// ============================================================================ -// Key Generation Benchmarks -// ============================================================================ - -func BenchmarkGenerateKey_NWIO(b *testing.B) { - for i := 0; i < b.N; i++ { - if _, err := nwio.GenerateKey(); err != nil { - b.Fatal(err) - } - } -} - -func BenchmarkGenerateKey_NBD(b *testing.B) { - for i := 0; i < b.N; i++ { - _ = nbd.GeneratePrivateKey() - } -} - -func BenchmarkGenerateKey_Fiat(b *testing.B) { - for i := 0; i < b.N; i++ { - _ = fiat.Generate() - } -} - -// ============================================================================ -// Event Signing Benchmarks -// ============================================================================ - -func BenchmarkEventSign_NWIO(b *testing.B) { - key, err := nwio.GenerateKey() - if err != nil { - b.Fatal(err) - } - b.ResetTimer() - - for i := 0; i < b.N; i++ { - evt := &nwio.Event{ - CreatedAt: 1672531200, - Kind: 1, - Tags: nwio.Tags{}, - Content: "Hello Nostr!", - } - if err := key.Sign(evt); err != nil { - b.Fatal(err) - } - } -} - -func BenchmarkEventSign_NBD(b *testing.B) { - sk := nbd.GeneratePrivateKey() - b.ResetTimer() - - for i := 0; i < b.N; i++ { - evt := &nbd.Event{ - CreatedAt: nbd.Timestamp(1672531200), - Kind: 1, - Tags: nbd.Tags{}, - Content: "Hello Nostr!", - } - if err := evt.Sign(sk); err != nil { - b.Fatal(err) - } - } -} - -func BenchmarkEventSign_Fiat(b *testing.B) { - sk := fiat.Generate() - b.ResetTimer() - - for i := 0; i < b.N; i++ { - evt := &fiat.Event{ - CreatedAt: fiat.Timestamp(1672531200), - Kind: 1, - Tags: fiat.Tags{}, - Content: "Hello Nostr!", - } - if err := evt.Sign(sk); err != nil { - b.Fatal(err) - } - } -} - -// ============================================================================ -// Event Verification Benchmarks -// ============================================================================ - -func BenchmarkEventVerify_NWIO(b *testing.B) { - // Create and sign an event - key, _ := nwio.GenerateKey() - evt := &nwio.Event{ - CreatedAt: 1672531200, - Kind: 1, - Tags: nwio.Tags{}, - Content: "Hello Nostr!", - } - key.Sign(evt) - - b.ResetTimer() - for i := 0; i < b.N; i++ { - if !evt.Verify() { - b.Fatal("verification failed") - } - } -} - -func BenchmarkEventVerify_NBD(b *testing.B) { - // Create and sign an event - sk := nbd.GeneratePrivateKey() - evt := &nbd.Event{ - CreatedAt: nbd.Timestamp(1672531200), - Kind: 1, - Tags: nbd.Tags{}, - Content: "Hello Nostr!", - } - evt.Sign(sk) - - b.ResetTimer() - for i := 0; i < b.N; i++ { - if ok, _ := evt.CheckSignature(); !ok { - b.Fatal("verification failed") - } - } -} - -func BenchmarkEventVerify_Fiat(b *testing.B) { - // Create and sign an event - sk := fiat.Generate() - evt := &fiat.Event{ - CreatedAt: fiat.Timestamp(1672531200), - Kind: 1, - Tags: fiat.Tags{}, - Content: "Hello Nostr!", - } - evt.Sign(sk) - - b.ResetTimer() - for i := 0; i < b.N; i++ { - if !evt.VerifySignature() { - b.Fatal("verification failed") - } - } -} - -// ============================================================================ -// Filter Matching Benchmarks -// ============================================================================ - -func BenchmarkFilterMatch_NWIO(b *testing.B) { - filter := &nwio.Filter{ - Kinds: []int{1}, - Authors: []string{samplePubKey}, - } - evt := &nwio.Event{ - PubKey: samplePubKey, - CreatedAt: 1672531200, - Kind: 1, - Content: "Hello Nostr!", - } - - b.ResetTimer() - for i := 0; i < b.N; i++ { - if !filter.Matches(evt) { - b.Fatal("filter should match") - } - } -} - -func BenchmarkFilterMatch_NBD(b *testing.B) { - filter := nbd.Filter{ - Kinds: []int{1}, - Authors: []string{samplePubKey}, - } - evt := &nbd.Event{ - PubKey: samplePubKey, - CreatedAt: nbd.Timestamp(1672531200), - Kind: 1, - Content: "Hello Nostr!", - } - - b.ResetTimer() - for i := 0; i < b.N; i++ { - if !filter.Matches(evt) { - b.Fatal("filter should match") - } - } -} - -func BenchmarkFilterMatch_Fiat(b *testing.B) { - pubkey, _ := fiat.PubKeyFromHex(samplePubKey) - filter := fiat.Filter{ - Kinds: []fiat.Kind{1}, - Authors: []fiat.PubKey{pubkey}, - } - evt := &fiat.Event{ - PubKey: pubkey, - CreatedAt: fiat.Timestamp(1672531200), - Kind: 1, - Content: "Hello Nostr!", - } - - b.ResetTimer() - for i := 0; i < b.N; i++ { - if !filter.Matches(*evt) { - b.Fatal("filter should match") - } - } -} - -// ============================================================================ -// Complex Filter Matching Benchmarks (with tags) -// ============================================================================ - -func BenchmarkFilterMatchComplex_NWIO(b *testing.B) { - filter := &nwio.Filter{ - Kinds: []int{1, 6, 7}, - Authors: []string{samplePubKey[:8]}, // Prefix match - Tags: map[string][]string{ - "e": {"5c83da77af1dec6d7289834998ad7aafbd9e2191396d75ec3cc27f5a77226f36"}, - }, - } - evt := &nwio.Event{ - PubKey: samplePubKey, - CreatedAt: 1672531200, - Kind: 1, - Tags: nwio.Tags{{"e", "5c83da77af1dec6d7289834998ad7aafbd9e2191396d75ec3cc27f5a77226f36"}}, - Content: "Hello Nostr!", - } - - b.ResetTimer() - for i := 0; i < b.N; i++ { - if !filter.Matches(evt) { - b.Fatal("filter should match") - } - } -} - -func BenchmarkFilterMatchComplex_NBD(b *testing.B) { - filter := nbd.Filter{ - Kinds: []int{1, 6, 7}, - Authors: []string{samplePubKey}, // NBD also supports prefix, use full key for simplicity - Tags: nbd.TagMap{ - "e": []string{"5c83da77af1dec6d7289834998ad7aafbd9e2191396d75ec3cc27f5a77226f36"}, - }, - } - evt := &nbd.Event{ - PubKey: samplePubKey, - CreatedAt: nbd.Timestamp(1672531200), - Kind: 1, - Tags: nbd.Tags{{"e", "5c83da77af1dec6d7289834998ad7aafbd9e2191396d75ec3cc27f5a77226f36"}}, - Content: "Hello Nostr!", - } - - b.ResetTimer() - for i := 0; i < b.N; i++ { - if !filter.Matches(evt) { - b.Fatal("filter should match") - } - } -} - -func BenchmarkFilterMatchComplex_Fiat(b *testing.B) { - pubkey, _ := fiat.PubKeyFromHex(samplePubKey) - - filter := fiat.Filter{ - Kinds: []fiat.Kind{1, 6, 7}, - Authors: []fiat.PubKey{pubkey}, // Use full pubkey for simplicity - Tags: fiat.TagMap{ - "e": []string{"5c83da77af1dec6d7289834998ad7aafbd9e2191396d75ec3cc27f5a77226f36"}, - }, - } - evt := &fiat.Event{ - PubKey: pubkey, - CreatedAt: fiat.Timestamp(1672531200), - Kind: 1, - Tags: fiat.Tags{{"e", "5c83da77af1dec6d7289834998ad7aafbd9e2191396d75ec3cc27f5a77226f36"}}, - Content: "Hello Nostr!", - } - - b.ResetTimer() - for i := 0; i < b.N; i++ { - if !filter.Matches(*evt) { - b.Fatal("filter should match") - } - } -} diff --git a/example_test.go b/example_test.go index 6d10ced..9a2aab1 100644 --- a/example_test.go +++ b/example_test.go @@ -5,7 +5,7 @@ import ( "fmt" "time" - "northwest.io/nostr" + "code.northwest.io/nostr" ) // Example_basic demonstrates basic usage of the nostr library. diff --git a/examples/basic/main.go b/examples/basic/main.go index 1a4061a..47092ef 100644 --- a/examples/basic/main.go +++ b/examples/basic/main.go @@ -6,7 +6,7 @@ import ( "os" "time" - "northwest.io/nostr" + "code.northwest.io/nostr" ) // Example_basic demonstrates basic usage of the nostr library. diff --git a/go.mod b/go.mod index 222b18d..e63be4c 100644 --- a/go.mod +++ b/go.mod @@ -1,4 +1,4 @@ -module northwest.io/nostr +module code.northwest.io/nostr go 1.25 diff --git a/relay.go b/relay.go index b34a61d..48bd4ae 100644 --- a/relay.go +++ b/relay.go @@ -6,7 +6,7 @@ import ( "fmt" "sync" - "northwest.io/nostr/internal/websocket" + "code.northwest.io/nostr/internal/websocket" ) // Relay represents a connection to a Nostr relay. diff --git a/relay_test.go b/relay_test.go index 38b2062..37d1a36 100644 --- a/relay_test.go +++ b/relay_test.go @@ -9,7 +9,7 @@ import ( "testing" "time" - "northwest.io/nostr/internal/websocket" + "code.northwest.io/nostr/internal/websocket" ) // mockRelay creates a test WebSocket server that echoes messages -- cgit v1.2.3