optimize e and p tags
This commit is contained in:
@@ -115,7 +115,8 @@
|
||||
"Bash(lynx:*)",
|
||||
"Bash(sed:*)",
|
||||
"Bash(docker stop:*)",
|
||||
"Bash(grep:*)"
|
||||
"Bash(grep:*)",
|
||||
"Bash(timeout 30 go test:*)"
|
||||
],
|
||||
"deny": [],
|
||||
"ask": []
|
||||
|
||||
194
cmd/benchmark/reports/run_20251122_190700/aggregate_report.txt
Normal file
194
cmd/benchmark/reports/run_20251122_190700/aggregate_report.txt
Normal file
@@ -0,0 +1,194 @@
|
||||
================================================================
|
||||
NOSTR RELAY BENCHMARK AGGREGATE REPORT
|
||||
================================================================
|
||||
Generated: 2025-11-22T19:37:27+00:00
|
||||
Benchmark Configuration:
|
||||
Events per test: 50000
|
||||
Concurrent workers: 24
|
||||
Test duration: 60s
|
||||
|
||||
Relays tested: 9
|
||||
|
||||
================================================================
|
||||
SUMMARY BY RELAY
|
||||
================================================================
|
||||
|
||||
Relay: rely-sqlite
|
||||
----------------------------------------
|
||||
Status: COMPLETED
|
||||
Events/sec: 15903.28
|
||||
Events/sec: 6308.59
|
||||
Events/sec: 15903.28
|
||||
Success Rate: 100.0%
|
||||
Success Rate: 100.0%
|
||||
Success Rate: 100.0%
|
||||
Avg Latency: 1.399274ms
|
||||
Bottom 10% Avg Latency: 746.992µs
|
||||
Avg Latency: 1.174853ms
|
||||
P95 Latency: 2.34974ms
|
||||
P95 Latency: 1.933092ms
|
||||
P95 Latency: 897.528µs
|
||||
|
||||
Relay: next-orly-badger
|
||||
----------------------------------------
|
||||
Status: COMPLETED
|
||||
Events/sec: 16607.66
|
||||
Events/sec: 5941.60
|
||||
Events/sec: 16607.66
|
||||
Success Rate: 100.0%
|
||||
Success Rate: 100.0%
|
||||
Success Rate: 100.0%
|
||||
Avg Latency: 1.338951ms
|
||||
Bottom 10% Avg Latency: 757.49µs
|
||||
Avg Latency: 1.490934ms
|
||||
P95 Latency: 2.047963ms
|
||||
P95 Latency: 2.961357ms
|
||||
P95 Latency: 928.904µs
|
||||
|
||||
Relay: next-orly-dgraph
|
||||
----------------------------------------
|
||||
Status: COMPLETED
|
||||
Events/sec: 16030.75
|
||||
Events/sec: 6221.38
|
||||
Events/sec: 16030.75
|
||||
Success Rate: 100.0%
|
||||
Success Rate: 100.0%
|
||||
Success Rate: 100.0%
|
||||
Avg Latency: 1.395117ms
|
||||
Bottom 10% Avg Latency: 759.404µs
|
||||
Avg Latency: 1.256755ms
|
||||
P95 Latency: 2.2327ms
|
||||
P95 Latency: 2.095959ms
|
||||
P95 Latency: 890.448µs
|
||||
|
||||
Relay: next-orly-neo4j
|
||||
----------------------------------------
|
||||
Status: COMPLETED
|
||||
Events/sec: 16565.07
|
||||
Events/sec: 6026.51
|
||||
Events/sec: 16565.07
|
||||
Success Rate: 100.0%
|
||||
Success Rate: 100.0%
|
||||
Success Rate: 100.0%
|
||||
Avg Latency: 1.32858ms
|
||||
Bottom 10% Avg Latency: 724.65µs
|
||||
Avg Latency: 1.392811ms
|
||||
P95 Latency: 2.11453ms
|
||||
P95 Latency: 2.568976ms
|
||||
P95 Latency: 910.826µs
|
||||
|
||||
Relay: khatru-sqlite
|
||||
----------------------------------------
|
||||
Status: COMPLETED
|
||||
Events/sec: 13273.11
|
||||
Events/sec: 6204.61
|
||||
Events/sec: 13273.11
|
||||
Success Rate: 100.0%
|
||||
Success Rate: 100.0%
|
||||
Success Rate: 100.0%
|
||||
Avg Latency: 1.732057ms
|
||||
Bottom 10% Avg Latency: 803.833µs
|
||||
Avg Latency: 1.263843ms
|
||||
P95 Latency: 3.370931ms
|
||||
P95 Latency: 2.195471ms
|
||||
P95 Latency: 905.805µs
|
||||
|
||||
Relay: khatru-badger
|
||||
----------------------------------------
|
||||
Status: COMPLETED
|
||||
Events/sec: 15590.07
|
||||
Events/sec: 6139.02
|
||||
Events/sec: 15590.07
|
||||
Success Rate: 100.0%
|
||||
Success Rate: 100.0%
|
||||
Success Rate: 100.0%
|
||||
Avg Latency: 1.451694ms
|
||||
Bottom 10% Avg Latency: 793.994µs
|
||||
Avg Latency: 1.324245ms
|
||||
P95 Latency: 2.351317ms
|
||||
P95 Latency: 2.291241ms
|
||||
P95 Latency: 901.036µs
|
||||
|
||||
Relay: relayer-basic
|
||||
----------------------------------------
|
||||
Status: COMPLETED
|
||||
Events/sec: 15076.33
|
||||
Events/sec: 6071.70
|
||||
Events/sec: 15076.33
|
||||
Success Rate: 100.0%
|
||||
Success Rate: 100.0%
|
||||
Success Rate: 100.0%
|
||||
Avg Latency: 1.517087ms
|
||||
Bottom 10% Avg Latency: 821.229µs
|
||||
Avg Latency: 1.385607ms
|
||||
P95 Latency: 2.48546ms
|
||||
P95 Latency: 2.478156ms
|
||||
P95 Latency: 916.474µs
|
||||
|
||||
Relay: strfry
|
||||
----------------------------------------
|
||||
Status: COMPLETED
|
||||
Events/sec: 16279.08
|
||||
Events/sec: 6097.81
|
||||
Events/sec: 16279.08
|
||||
Success Rate: 100.0%
|
||||
Success Rate: 100.0%
|
||||
Success Rate: 100.0%
|
||||
Avg Latency: 1.369757ms
|
||||
Bottom 10% Avg Latency: 764.155µs
|
||||
Avg Latency: 1.369895ms
|
||||
P95 Latency: 2.13361ms
|
||||
P95 Latency: 2.341095ms
|
||||
P95 Latency: 894.733µs
|
||||
|
||||
Relay: nostr-rs-relay
|
||||
----------------------------------------
|
||||
Status: COMPLETED
|
||||
Events/sec: 14836.18
|
||||
Events/sec: 6111.29
|
||||
Events/sec: 14836.18
|
||||
Success Rate: 100.0%
|
||||
Success Rate: 100.0%
|
||||
Success Rate: 100.0%
|
||||
Avg Latency: 1.545053ms
|
||||
Bottom 10% Avg Latency: 829.94µs
|
||||
Avg Latency: 1.336805ms
|
||||
P95 Latency: 2.562666ms
|
||||
P95 Latency: 2.417039ms
|
||||
P95 Latency: 936.832µs
|
||||
|
||||
|
||||
================================================================
|
||||
DETAILED RESULTS
|
||||
================================================================
|
||||
|
||||
Individual relay reports are available in:
|
||||
- /reports/run_20251122_190700/khatru-badger_results.txt
|
||||
- /reports/run_20251122_190700/khatru-sqlite_results.txt
|
||||
- /reports/run_20251122_190700/next-orly-badger_results.txt
|
||||
- /reports/run_20251122_190700/next-orly-dgraph_results.txt
|
||||
- /reports/run_20251122_190700/next-orly-neo4j_results.txt
|
||||
- /reports/run_20251122_190700/nostr-rs-relay_results.txt
|
||||
- /reports/run_20251122_190700/relayer-basic_results.txt
|
||||
- /reports/run_20251122_190700/rely-sqlite_results.txt
|
||||
- /reports/run_20251122_190700/strfry_results.txt
|
||||
|
||||
================================================================
|
||||
BENCHMARK COMPARISON TABLE
|
||||
================================================================
|
||||
|
||||
Relay Status Peak Tput/s Avg Latency Success Rate
|
||||
---- ------ ----------- ----------- ------------
|
||||
rely-sqlite OK 15903.28 1.399274ms 100.0%
|
||||
next-orly-badger OK 16607.66 1.338951ms 100.0%
|
||||
next-orly-dgraph OK 16030.75 1.395117ms 100.0%
|
||||
next-orly-neo4j OK 16565.07 1.32858ms 100.0%
|
||||
khatru-sqlite OK 13273.11 1.732057ms 100.0%
|
||||
khatru-badger OK 15590.07 1.451694ms 100.0%
|
||||
relayer-basic OK 15076.33 1.517087ms 100.0%
|
||||
strfry OK 16279.08 1.369757ms 100.0%
|
||||
nostr-rs-relay OK 14836.18 1.545053ms 100.0%
|
||||
|
||||
================================================================
|
||||
End of Report
|
||||
================================================================
|
||||
@@ -0,0 +1,198 @@
|
||||
Starting Nostr Relay Benchmark (Badger Backend)
|
||||
Data Directory: /tmp/benchmark_khatru-badger_8
|
||||
Events: 50000, Workers: 24, Duration: 1m0s
|
||||
1763839435106544ℹ️ migrating to version 1... /build/pkg/database/migrations.go:66
|
||||
1763839435106604ℹ️ migrating to version 2... /build/pkg/database/migrations.go:73
|
||||
1763839435106631ℹ️ migrating to version 3... /build/pkg/database/migrations.go:80
|
||||
1763839435106637ℹ️ cleaning up ephemeral events (kinds 20000-29999)... /build/pkg/database/migrations.go:294
|
||||
1763839435106651ℹ️ cleaned up 0 ephemeral events from database /build/pkg/database/migrations.go:339
|
||||
1763839435106670ℹ️ migrating to version 4... /build/pkg/database/migrations.go:87
|
||||
1763839435106676ℹ️ converting events to optimized inline storage (Reiser4 optimization)... /build/pkg/database/migrations.go:347
|
||||
1763839435106697ℹ️ found 0 events to convert (0 regular, 0 replaceable, 0 addressable) /build/pkg/database/migrations.go:436
|
||||
1763839435106704ℹ️ migration complete: converted 0 events to optimized inline storage, deleted 0 old keys /build/pkg/database/migrations.go:545
|
||||
1763839435106780ℹ️ migrating to version 5... /build/pkg/database/migrations.go:94
|
||||
1763839435106787ℹ️ re-encoding events with optimized tag binary format... /build/pkg/database/migrations.go:552
|
||||
1763839435106802ℹ️ found 0 events with e/p tags to re-encode /build/pkg/database/migrations.go:639
|
||||
1763839435106808ℹ️ no events need re-encoding /build/pkg/database/migrations.go:642
|
||||
|
||||
╔════════════════════════════════════════════════════════╗
|
||||
║ BADGER BACKEND BENCHMARK SUITE ║
|
||||
╚════════════════════════════════════════════════════════╝
|
||||
|
||||
=== Starting Badger benchmark ===
|
||||
RunPeakThroughputTest (Badger)..
|
||||
|
||||
=== Peak Throughput Test ===
|
||||
2025/11/22 19:23:55 WARN: Failed to load embedded library from /tmp/orly-libsecp256k1/libsecp256k1.so: Error relocating /tmp/orly-libsecp256k1/libsecp256k1.so: __fprintf_chk: symbol not found, falling back to system paths
|
||||
2025/11/22 19:23:55 INFO: Successfully loaded libsecp256k1 v5.0.0 from system path: libsecp256k1.so.2
|
||||
Events saved: 50000/50000 (100.0%), errors: 0
|
||||
Duration: 3.207170539s
|
||||
Events/sec: 15590.07
|
||||
Avg latency: 1.451694ms
|
||||
P90 latency: 1.980821ms
|
||||
P95 latency: 2.351317ms
|
||||
P99 latency: 3.85562ms
|
||||
Bottom 10% Avg latency: 793.994µs
|
||||
Wiping database between tests...
|
||||
RunBurstPatternTest (Badger)..
|
||||
|
||||
=== Burst Pattern Test ===
|
||||
Burst completed: 5000 events in 285.869262ms
|
||||
Burst completed: 5000 events in 342.789614ms
|
||||
Burst completed: 5000 events in 294.148662ms
|
||||
Burst completed: 5000 events in 312.162616ms
|
||||
Burst completed: 5000 events in 285.282311ms
|
||||
Burst completed: 5000 events in 401.532953ms
|
||||
Burst completed: 5000 events in 303.869144ms
|
||||
Burst completed: 5000 events in 319.670695ms
|
||||
Burst completed: 5000 events in 325.238604ms
|
||||
Burst completed: 5000 events in 269.150105ms
|
||||
Burst test completed: 50000 events in 8.144623588s, errors: 0
|
||||
Events/sec: 6139.02
|
||||
Wiping database between tests...
|
||||
RunMixedReadWriteTest (Badger)..
|
||||
|
||||
=== Mixed Read/Write Test ===
|
||||
Generating 1000 unique synthetic events (minimum 300 bytes each)...
|
||||
Generated 1000 events:
|
||||
Average content size: 312 bytes
|
||||
All events are unique (incremental timestamps)
|
||||
All events are properly signed
|
||||
|
||||
Pre-populating database for read tests...
|
||||
Generating 50000 unique synthetic events (minimum 300 bytes each)...
|
||||
Generated 50000 events:
|
||||
Average content size: 314 bytes
|
||||
All events are unique (incremental timestamps)
|
||||
All events are properly signed
|
||||
|
||||
Mixed test completed: 25000 writes, 25000 reads in 24.634143457s
|
||||
Combined ops/sec: 2029.70
|
||||
Wiping database between tests...
|
||||
RunQueryTest (Badger)..
|
||||
|
||||
=== Query Test ===
|
||||
Generating 10000 unique synthetic events (minimum 300 bytes each)...
|
||||
Generated 10000 events:
|
||||
Average content size: 313 bytes
|
||||
All events are unique (incremental timestamps)
|
||||
All events are properly signed
|
||||
|
||||
Pre-populating database with 10000 events for query tests...
|
||||
Query test completed: 383293 queries in 1m0.006743126s
|
||||
Queries/sec: 6387.50
|
||||
Avg query latency: 1.745128ms
|
||||
P95 query latency: 7.082542ms
|
||||
P99 query latency: 11.228263ms
|
||||
Wiping database between tests...
|
||||
RunConcurrentQueryStoreTest (Badger)..
|
||||
|
||||
=== Concurrent Query/Store Test ===
|
||||
Generating 5000 unique synthetic events (minimum 300 bytes each)...
|
||||
Generated 5000 events:
|
||||
Average content size: 313 bytes
|
||||
All events are unique (incremental timestamps)
|
||||
All events are properly signed
|
||||
|
||||
Pre-populating database with 5000 events for concurrent query/store test...
|
||||
Generating 50000 unique synthetic events (minimum 300 bytes each)...
|
||||
Generated 50000 events:
|
||||
Average content size: 314 bytes
|
||||
All events are unique (incremental timestamps)
|
||||
All events are properly signed
|
||||
|
||||
Concurrent test completed: 314586 operations (264586 queries, 50000 writes) in 1m0.003644928s
|
||||
Operations/sec: 5242.78
|
||||
Avg latency: 1.487422ms
|
||||
Avg query latency: 1.448842ms
|
||||
Avg write latency: 1.691574ms
|
||||
P95 latency: 3.789773ms
|
||||
P99 latency: 6.325059ms
|
||||
|
||||
=== Badger benchmark completed ===
|
||||
|
||||
|
||||
================================================================================
|
||||
BENCHMARK REPORT
|
||||
================================================================================
|
||||
|
||||
Test: Peak Throughput
|
||||
Duration: 3.207170539s
|
||||
Total Events: 50000
|
||||
Events/sec: 15590.07
|
||||
Success Rate: 100.0%
|
||||
Concurrent Workers: 24
|
||||
Memory Used: 98 MB
|
||||
Avg Latency: 1.451694ms
|
||||
P90 Latency: 1.980821ms
|
||||
P95 Latency: 2.351317ms
|
||||
P99 Latency: 3.85562ms
|
||||
Bottom 10% Avg Latency: 793.994µs
|
||||
----------------------------------------
|
||||
|
||||
Test: Burst Pattern
|
||||
Duration: 8.144623588s
|
||||
Total Events: 50000
|
||||
Events/sec: 6139.02
|
||||
Success Rate: 100.0%
|
||||
Concurrent Workers: 24
|
||||
Memory Used: 178 MB
|
||||
Avg Latency: 1.324245ms
|
||||
P90 Latency: 1.946456ms
|
||||
P95 Latency: 2.291241ms
|
||||
P99 Latency: 3.488291ms
|
||||
Bottom 10% Avg Latency: 514.259µs
|
||||
----------------------------------------
|
||||
|
||||
Test: Mixed Read/Write
|
||||
Duration: 24.634143457s
|
||||
Total Events: 50000
|
||||
Events/sec: 2029.70
|
||||
Success Rate: 100.0%
|
||||
Concurrent Workers: 24
|
||||
Memory Used: 142 MB
|
||||
Avg Latency: 389.015µs
|
||||
P90 Latency: 806.956µs
|
||||
P95 Latency: 901.036µs
|
||||
P99 Latency: 1.133428ms
|
||||
Bottom 10% Avg Latency: 1.055235ms
|
||||
----------------------------------------
|
||||
|
||||
Test: Query Performance
|
||||
Duration: 1m0.006743126s
|
||||
Total Events: 383293
|
||||
Events/sec: 6387.50
|
||||
Success Rate: 100.0%
|
||||
Concurrent Workers: 24
|
||||
Memory Used: 159 MB
|
||||
Avg Latency: 1.745128ms
|
||||
P90 Latency: 5.322842ms
|
||||
P95 Latency: 7.082542ms
|
||||
P99 Latency: 11.228263ms
|
||||
Bottom 10% Avg Latency: 7.913494ms
|
||||
----------------------------------------
|
||||
|
||||
Test: Concurrent Query/Store
|
||||
Duration: 1m0.003644928s
|
||||
Total Events: 314586
|
||||
Events/sec: 5242.78
|
||||
Success Rate: 100.0%
|
||||
Concurrent Workers: 24
|
||||
Memory Used: 107 MB
|
||||
Avg Latency: 1.487422ms
|
||||
P90 Latency: 2.95774ms
|
||||
P95 Latency: 3.789773ms
|
||||
P99 Latency: 6.325059ms
|
||||
Bottom 10% Avg Latency: 4.427784ms
|
||||
----------------------------------------
|
||||
|
||||
Report saved to: /tmp/benchmark_khatru-badger_8/benchmark_report.txt
|
||||
AsciiDoc report saved to: /tmp/benchmark_khatru-badger_8/benchmark_report.adoc
|
||||
|
||||
RELAY_NAME: khatru-badger
|
||||
RELAY_URL: ws://khatru-badger:3334
|
||||
TEST_TIMESTAMP: 2025-11-22T19:27:12+00:00
|
||||
BENCHMARK_CONFIG:
|
||||
Events: 50000
|
||||
Workers: 24
|
||||
Duration: 60s
|
||||
@@ -0,0 +1,198 @@
|
||||
Starting Nostr Relay Benchmark (Badger Backend)
|
||||
Data Directory: /tmp/benchmark_khatru-sqlite_8
|
||||
Events: 50000, Workers: 24, Duration: 1m0s
|
||||
1763839231750842ℹ️ migrating to version 1... /build/pkg/database/migrations.go:66
|
||||
1763839231750901ℹ️ migrating to version 2... /build/pkg/database/migrations.go:73
|
||||
1763839231750925ℹ️ migrating to version 3... /build/pkg/database/migrations.go:80
|
||||
1763839231750931ℹ️ cleaning up ephemeral events (kinds 20000-29999)... /build/pkg/database/migrations.go:294
|
||||
1763839231750941ℹ️ cleaned up 0 ephemeral events from database /build/pkg/database/migrations.go:339
|
||||
1763839231750956ℹ️ migrating to version 4... /build/pkg/database/migrations.go:87
|
||||
1763839231750961ℹ️ converting events to optimized inline storage (Reiser4 optimization)... /build/pkg/database/migrations.go:347
|
||||
1763839231750983ℹ️ found 0 events to convert (0 regular, 0 replaceable, 0 addressable) /build/pkg/database/migrations.go:436
|
||||
1763839231750993ℹ️ migration complete: converted 0 events to optimized inline storage, deleted 0 old keys /build/pkg/database/migrations.go:545
|
||||
1763839231751016ℹ️ migrating to version 5... /build/pkg/database/migrations.go:94
|
||||
1763839231751021ℹ️ re-encoding events with optimized tag binary format... /build/pkg/database/migrations.go:552
|
||||
1763839231751033ℹ️ found 0 events with e/p tags to re-encode /build/pkg/database/migrations.go:639
|
||||
1763839231751038ℹ️ no events need re-encoding /build/pkg/database/migrations.go:642
|
||||
|
||||
╔════════════════════════════════════════════════════════╗
|
||||
║ BADGER BACKEND BENCHMARK SUITE ║
|
||||
╚════════════════════════════════════════════════════════╝
|
||||
|
||||
=== Starting Badger benchmark ===
|
||||
RunPeakThroughputTest (Badger)..
|
||||
|
||||
=== Peak Throughput Test ===
|
||||
2025/11/22 19:20:31 WARN: Failed to load embedded library from /tmp/orly-libsecp256k1/libsecp256k1.so: Error relocating /tmp/orly-libsecp256k1/libsecp256k1.so: __fprintf_chk: symbol not found, falling back to system paths
|
||||
2025/11/22 19:20:31 INFO: Successfully loaded libsecp256k1 v5.0.0 from system path: libsecp256k1.so.2
|
||||
Events saved: 50000/50000 (100.0%), errors: 0
|
||||
Duration: 3.76701384s
|
||||
Events/sec: 13273.11
|
||||
Avg latency: 1.732057ms
|
||||
P90 latency: 2.725001ms
|
||||
P95 latency: 3.370931ms
|
||||
P99 latency: 5.636846ms
|
||||
Bottom 10% Avg latency: 803.833µs
|
||||
Wiping database between tests...
|
||||
RunBurstPatternTest (Badger)..
|
||||
|
||||
=== Burst Pattern Test ===
|
||||
Burst completed: 5000 events in 324.962224ms
|
||||
Burst completed: 5000 events in 319.788529ms
|
||||
Burst completed: 5000 events in 292.223747ms
|
||||
Burst completed: 5000 events in 297.968607ms
|
||||
Burst completed: 5000 events in 285.831691ms
|
||||
Burst completed: 5000 events in 385.949074ms
|
||||
Burst completed: 5000 events in 290.335776ms
|
||||
Burst completed: 5000 events in 276.875448ms
|
||||
Burst completed: 5000 events in 304.201963ms
|
||||
Burst completed: 5000 events in 273.277754ms
|
||||
Burst test completed: 50000 events in 8.058529464s, errors: 0
|
||||
Events/sec: 6204.61
|
||||
Wiping database between tests...
|
||||
RunMixedReadWriteTest (Badger)..
|
||||
|
||||
=== Mixed Read/Write Test ===
|
||||
Generating 1000 unique synthetic events (minimum 300 bytes each)...
|
||||
Generated 1000 events:
|
||||
Average content size: 312 bytes
|
||||
All events are unique (incremental timestamps)
|
||||
All events are properly signed
|
||||
|
||||
Pre-populating database for read tests...
|
||||
Generating 50000 unique synthetic events (minimum 300 bytes each)...
|
||||
Generated 50000 events:
|
||||
Average content size: 314 bytes
|
||||
All events are unique (incremental timestamps)
|
||||
All events are properly signed
|
||||
|
||||
Mixed test completed: 25000 writes, 25000 reads in 24.559984136s
|
||||
Combined ops/sec: 2035.83
|
||||
Wiping database between tests...
|
||||
RunQueryTest (Badger)..
|
||||
|
||||
=== Query Test ===
|
||||
Generating 10000 unique synthetic events (minimum 300 bytes each)...
|
||||
Generated 10000 events:
|
||||
Average content size: 313 bytes
|
||||
All events are unique (incremental timestamps)
|
||||
All events are properly signed
|
||||
|
||||
Pre-populating database with 10000 events for query tests...
|
||||
Query test completed: 382812 queries in 1m0.004759428s
|
||||
Queries/sec: 6379.69
|
||||
Avg query latency: 1.753564ms
|
||||
P95 query latency: 7.120429ms
|
||||
P99 query latency: 11.234021ms
|
||||
Wiping database between tests...
|
||||
RunConcurrentQueryStoreTest (Badger)..
|
||||
|
||||
=== Concurrent Query/Store Test ===
|
||||
Generating 5000 unique synthetic events (minimum 300 bytes each)...
|
||||
Generated 5000 events:
|
||||
Average content size: 313 bytes
|
||||
All events are unique (incremental timestamps)
|
||||
All events are properly signed
|
||||
|
||||
Pre-populating database with 5000 events for concurrent query/store test...
|
||||
Generating 50000 unique synthetic events (minimum 300 bytes each)...
|
||||
Generated 50000 events:
|
||||
Average content size: 314 bytes
|
||||
All events are unique (incremental timestamps)
|
||||
All events are properly signed
|
||||
|
||||
Concurrent test completed: 310209 operations (260209 queries, 50000 writes) in 1m0.002874017s
|
||||
Operations/sec: 5169.90
|
||||
Avg latency: 1.497119ms
|
||||
Avg query latency: 1.472534ms
|
||||
Avg write latency: 1.625063ms
|
||||
P95 latency: 3.842736ms
|
||||
P99 latency: 6.293151ms
|
||||
|
||||
=== Badger benchmark completed ===
|
||||
|
||||
|
||||
================================================================================
|
||||
BENCHMARK REPORT
|
||||
================================================================================
|
||||
|
||||
Test: Peak Throughput
|
||||
Duration: 3.76701384s
|
||||
Total Events: 50000
|
||||
Events/sec: 13273.11
|
||||
Success Rate: 100.0%
|
||||
Concurrent Workers: 24
|
||||
Memory Used: 133 MB
|
||||
Avg Latency: 1.732057ms
|
||||
P90 Latency: 2.725001ms
|
||||
P95 Latency: 3.370931ms
|
||||
P99 Latency: 5.636846ms
|
||||
Bottom 10% Avg Latency: 803.833µs
|
||||
----------------------------------------
|
||||
|
||||
Test: Burst Pattern
|
||||
Duration: 8.058529464s
|
||||
Total Events: 50000
|
||||
Events/sec: 6204.61
|
||||
Success Rate: 100.0%
|
||||
Concurrent Workers: 24
|
||||
Memory Used: 196 MB
|
||||
Avg Latency: 1.263843ms
|
||||
P90 Latency: 1.851055ms
|
||||
P95 Latency: 2.195471ms
|
||||
P99 Latency: 3.218951ms
|
||||
Bottom 10% Avg Latency: 504.149µs
|
||||
----------------------------------------
|
||||
|
||||
Test: Mixed Read/Write
|
||||
Duration: 24.559984136s
|
||||
Total Events: 50000
|
||||
Events/sec: 2035.83
|
||||
Success Rate: 100.0%
|
||||
Concurrent Workers: 24
|
||||
Memory Used: 127 MB
|
||||
Avg Latency: 390.903µs
|
||||
P90 Latency: 809.291µs
|
||||
P95 Latency: 905.805µs
|
||||
P99 Latency: 1.149089ms
|
||||
Bottom 10% Avg Latency: 1.046555ms
|
||||
----------------------------------------
|
||||
|
||||
Test: Query Performance
|
||||
Duration: 1m0.004759428s
|
||||
Total Events: 382812
|
||||
Events/sec: 6379.69
|
||||
Success Rate: 100.0%
|
||||
Concurrent Workers: 24
|
||||
Memory Used: 118 MB
|
||||
Avg Latency: 1.753564ms
|
||||
P90 Latency: 5.356742ms
|
||||
P95 Latency: 7.120429ms
|
||||
P99 Latency: 11.234021ms
|
||||
Bottom 10% Avg Latency: 7.946956ms
|
||||
----------------------------------------
|
||||
|
||||
Test: Concurrent Query/Store
|
||||
Duration: 1m0.002874017s
|
||||
Total Events: 310209
|
||||
Events/sec: 5169.90
|
||||
Success Rate: 100.0%
|
||||
Concurrent Workers: 24
|
||||
Memory Used: 123 MB
|
||||
Avg Latency: 1.497119ms
|
||||
P90 Latency: 2.998239ms
|
||||
P95 Latency: 3.842736ms
|
||||
P99 Latency: 6.293151ms
|
||||
Bottom 10% Avg Latency: 4.449237ms
|
||||
----------------------------------------
|
||||
|
||||
Report saved to: /tmp/benchmark_khatru-sqlite_8/benchmark_report.txt
|
||||
AsciiDoc report saved to: /tmp/benchmark_khatru-sqlite_8/benchmark_report.adoc
|
||||
|
||||
RELAY_NAME: khatru-sqlite
|
||||
RELAY_URL: ws://khatru-sqlite:3334
|
||||
TEST_TIMESTAMP: 2025-11-22T19:23:50+00:00
|
||||
BENCHMARK_CONFIG:
|
||||
Events: 50000
|
||||
Workers: 24
|
||||
Duration: 60s
|
||||
@@ -0,0 +1,198 @@
|
||||
Starting Nostr Relay Benchmark (Badger Backend)
|
||||
Data Directory: /tmp/benchmark_next-orly-badger_8
|
||||
Events: 50000, Workers: 24, Duration: 1m0s
|
||||
1763838623230113ℹ️ migrating to version 1... /build/pkg/database/migrations.go:66
|
||||
1763838623230189ℹ️ migrating to version 2... /build/pkg/database/migrations.go:73
|
||||
1763838623230211ℹ️ migrating to version 3... /build/pkg/database/migrations.go:80
|
||||
1763838623230216ℹ️ cleaning up ephemeral events (kinds 20000-29999)... /build/pkg/database/migrations.go:294
|
||||
1763838623230227ℹ️ cleaned up 0 ephemeral events from database /build/pkg/database/migrations.go:339
|
||||
1763838623230248ℹ️ migrating to version 4... /build/pkg/database/migrations.go:87
|
||||
1763838623230253ℹ️ converting events to optimized inline storage (Reiser4 optimization)... /build/pkg/database/migrations.go:347
|
||||
1763838623230263ℹ️ found 0 events to convert (0 regular, 0 replaceable, 0 addressable) /build/pkg/database/migrations.go:436
|
||||
1763838623230268ℹ️ migration complete: converted 0 events to optimized inline storage, deleted 0 old keys /build/pkg/database/migrations.go:545
|
||||
1763838623230283ℹ️ migrating to version 5... /build/pkg/database/migrations.go:94
|
||||
1763838623230287ℹ️ re-encoding events with optimized tag binary format... /build/pkg/database/migrations.go:552
|
||||
1763838623230296ℹ️ found 0 events with e/p tags to re-encode /build/pkg/database/migrations.go:639
|
||||
1763838623230301ℹ️ no events need re-encoding /build/pkg/database/migrations.go:642
|
||||
|
||||
╔════════════════════════════════════════════════════════╗
|
||||
║ BADGER BACKEND BENCHMARK SUITE ║
|
||||
╚════════════════════════════════════════════════════════╝
|
||||
|
||||
=== Starting Badger benchmark ===
|
||||
RunPeakThroughputTest (Badger)..
|
||||
|
||||
=== Peak Throughput Test ===
|
||||
2025/11/22 19:10:23 WARN: Failed to load embedded library from /tmp/orly-libsecp256k1/libsecp256k1.so: Error relocating /tmp/orly-libsecp256k1/libsecp256k1.so: __fprintf_chk: symbol not found, falling back to system paths
|
||||
2025/11/22 19:10:23 INFO: Successfully loaded libsecp256k1 v5.0.0 from system path: libsecp256k1.so.2
|
||||
Events saved: 50000/50000 (100.0%), errors: 0
|
||||
Duration: 3.010658794s
|
||||
Events/sec: 16607.66
|
||||
Avg latency: 1.338951ms
|
||||
P90 latency: 1.788958ms
|
||||
P95 latency: 2.047963ms
|
||||
P99 latency: 2.856809ms
|
||||
Bottom 10% Avg latency: 757.49µs
|
||||
Wiping database between tests...
|
||||
RunBurstPatternTest (Badger)..
|
||||
|
||||
=== Burst Pattern Test ===
|
||||
Burst completed: 5000 events in 291.670556ms
|
||||
Burst completed: 5000 events in 360.87238ms
|
||||
Burst completed: 5000 events in 301.408062ms
|
||||
Burst completed: 5000 events in 316.375958ms
|
||||
Burst completed: 5000 events in 376.937291ms
|
||||
Burst completed: 5000 events in 566.001876ms
|
||||
Burst completed: 5000 events in 315.464051ms
|
||||
Burst completed: 5000 events in 317.465099ms
|
||||
Burst completed: 5000 events in 278.045601ms
|
||||
Burst completed: 5000 events in 284.298545ms
|
||||
Burst test completed: 50000 events in 8.415248481s, errors: 0
|
||||
Events/sec: 5941.60
|
||||
Wiping database between tests...
|
||||
RunMixedReadWriteTest (Badger)..
|
||||
|
||||
=== Mixed Read/Write Test ===
|
||||
Generating 1000 unique synthetic events (minimum 300 bytes each)...
|
||||
Generated 1000 events:
|
||||
Average content size: 312 bytes
|
||||
All events are unique (incremental timestamps)
|
||||
All events are properly signed
|
||||
|
||||
Pre-populating database for read tests...
|
||||
Generating 50000 unique synthetic events (minimum 300 bytes each)...
|
||||
Generated 50000 events:
|
||||
Average content size: 314 bytes
|
||||
All events are unique (incremental timestamps)
|
||||
All events are properly signed
|
||||
|
||||
Mixed test completed: 25000 writes, 25000 reads in 24.625034214s
|
||||
Combined ops/sec: 2030.45
|
||||
Wiping database between tests...
|
||||
RunQueryTest (Badger)..
|
||||
|
||||
=== Query Test ===
|
||||
Generating 10000 unique synthetic events (minimum 300 bytes each)...
|
||||
Generated 10000 events:
|
||||
Average content size: 313 bytes
|
||||
All events are unique (incremental timestamps)
|
||||
All events are properly signed
|
||||
|
||||
Pre-populating database with 10000 events for query tests...
|
||||
Query test completed: 381027 queries in 1m0.006635598s
|
||||
Queries/sec: 6349.75
|
||||
Avg query latency: 1.772811ms
|
||||
P95 query latency: 7.236356ms
|
||||
P99 query latency: 11.279564ms
|
||||
Wiping database between tests...
|
||||
RunConcurrentQueryStoreTest (Badger)..
|
||||
|
||||
=== Concurrent Query/Store Test ===
|
||||
Generating 5000 unique synthetic events (minimum 300 bytes each)...
|
||||
Generated 5000 events:
|
||||
Average content size: 313 bytes
|
||||
All events are unique (incremental timestamps)
|
||||
All events are properly signed
|
||||
|
||||
Pre-populating database with 5000 events for concurrent query/store test...
|
||||
Generating 50000 unique synthetic events (minimum 300 bytes each)...
|
||||
Generated 50000 events:
|
||||
Average content size: 314 bytes
|
||||
All events are unique (incremental timestamps)
|
||||
All events are properly signed
|
||||
|
||||
Concurrent test completed: 305823 operations (255823 queries, 50000 writes) in 1m0.003583098s
|
||||
Operations/sec: 5096.75
|
||||
Avg latency: 1.56258ms
|
||||
Avg query latency: 1.51784ms
|
||||
Avg write latency: 1.791487ms
|
||||
P95 latency: 4.018388ms
|
||||
P99 latency: 7.130801ms
|
||||
|
||||
=== Badger benchmark completed ===
|
||||
|
||||
|
||||
================================================================================
|
||||
BENCHMARK REPORT
|
||||
================================================================================
|
||||
|
||||
Test: Peak Throughput
|
||||
Duration: 3.010658794s
|
||||
Total Events: 50000
|
||||
Events/sec: 16607.66
|
||||
Success Rate: 100.0%
|
||||
Concurrent Workers: 24
|
||||
Memory Used: 129 MB
|
||||
Avg Latency: 1.338951ms
|
||||
P90 Latency: 1.788958ms
|
||||
P95 Latency: 2.047963ms
|
||||
P99 Latency: 2.856809ms
|
||||
Bottom 10% Avg Latency: 757.49µs
|
||||
----------------------------------------
|
||||
|
||||
Test: Burst Pattern
|
||||
Duration: 8.415248481s
|
||||
Total Events: 50000
|
||||
Events/sec: 5941.60
|
||||
Success Rate: 100.0%
|
||||
Concurrent Workers: 24
|
||||
Memory Used: 211 MB
|
||||
Avg Latency: 1.490934ms
|
||||
P90 Latency: 2.351964ms
|
||||
P95 Latency: 2.961357ms
|
||||
P99 Latency: 5.082311ms
|
||||
Bottom 10% Avg Latency: 562.053µs
|
||||
----------------------------------------
|
||||
|
||||
Test: Mixed Read/Write
|
||||
Duration: 24.625034214s
|
||||
Total Events: 50000
|
||||
Events/sec: 2030.45
|
||||
Success Rate: 100.0%
|
||||
Concurrent Workers: 24
|
||||
Memory Used: 131 MB
|
||||
Avg Latency: 399.173µs
|
||||
P90 Latency: 823.303µs
|
||||
P95 Latency: 928.904µs
|
||||
P99 Latency: 1.225059ms
|
||||
Bottom 10% Avg Latency: 1.081556ms
|
||||
----------------------------------------
|
||||
|
||||
Test: Query Performance
|
||||
Duration: 1m0.006635598s
|
||||
Total Events: 381027
|
||||
Events/sec: 6349.75
|
||||
Success Rate: 100.0%
|
||||
Concurrent Workers: 24
|
||||
Memory Used: 100 MB
|
||||
Avg Latency: 1.772811ms
|
||||
P90 Latency: 5.462421ms
|
||||
P95 Latency: 7.236356ms
|
||||
P99 Latency: 11.279564ms
|
||||
Bottom 10% Avg Latency: 8.018763ms
|
||||
----------------------------------------
|
||||
|
||||
Test: Concurrent Query/Store
|
||||
Duration: 1m0.003583098s
|
||||
Total Events: 305823
|
||||
Events/sec: 5096.75
|
||||
Success Rate: 100.0%
|
||||
Concurrent Workers: 24
|
||||
Memory Used: 99 MB
|
||||
Avg Latency: 1.56258ms
|
||||
P90 Latency: 3.106468ms
|
||||
P95 Latency: 4.018388ms
|
||||
P99 Latency: 7.130801ms
|
||||
Bottom 10% Avg Latency: 4.803925ms
|
||||
----------------------------------------
|
||||
|
||||
Report saved to: /tmp/benchmark_next-orly-badger_8/benchmark_report.txt
|
||||
AsciiDoc report saved to: /tmp/benchmark_next-orly-badger_8/benchmark_report.adoc
|
||||
|
||||
RELAY_NAME: next-orly-badger
|
||||
RELAY_URL: ws://next-orly-badger:8080
|
||||
TEST_TIMESTAMP: 2025-11-22T19:13:41+00:00
|
||||
BENCHMARK_CONFIG:
|
||||
Events: 50000
|
||||
Workers: 24
|
||||
Duration: 60s
|
||||
@@ -0,0 +1,198 @@
|
||||
Starting Nostr Relay Benchmark (Badger Backend)
|
||||
Data Directory: /tmp/benchmark_next-orly-dgraph_8
|
||||
Events: 50000, Workers: 24, Duration: 1m0s
|
||||
1763838826199118ℹ️ migrating to version 1... /build/pkg/database/migrations.go:66
|
||||
1763838826199210ℹ️ migrating to version 2... /build/pkg/database/migrations.go:73
|
||||
1763838826199247ℹ️ migrating to version 3... /build/pkg/database/migrations.go:80
|
||||
1763838826199256ℹ️ cleaning up ephemeral events (kinds 20000-29999)... /build/pkg/database/migrations.go:294
|
||||
1763838826199269ℹ️ cleaned up 0 ephemeral events from database /build/pkg/database/migrations.go:339
|
||||
1763838826199289ℹ️ migrating to version 4... /build/pkg/database/migrations.go:87
|
||||
1763838826199295ℹ️ converting events to optimized inline storage (Reiser4 optimization)... /build/pkg/database/migrations.go:347
|
||||
1763838826199309ℹ️ found 0 events to convert (0 regular, 0 replaceable, 0 addressable) /build/pkg/database/migrations.go:436
|
||||
1763838826199316ℹ️ migration complete: converted 0 events to optimized inline storage, deleted 0 old keys /build/pkg/database/migrations.go:545
|
||||
1763838826199335ℹ️ migrating to version 5... /build/pkg/database/migrations.go:94
|
||||
1763838826199341ℹ️ re-encoding events with optimized tag binary format... /build/pkg/database/migrations.go:552
|
||||
1763838826199351ℹ️ found 0 events with e/p tags to re-encode /build/pkg/database/migrations.go:639
|
||||
1763838826199356ℹ️ no events need re-encoding /build/pkg/database/migrations.go:642
|
||||
|
||||
╔════════════════════════════════════════════════════════╗
|
||||
║ BADGER BACKEND BENCHMARK SUITE ║
|
||||
╚════════════════════════════════════════════════════════╝
|
||||
|
||||
=== Starting Badger benchmark ===
|
||||
RunPeakThroughputTest (Badger)..
|
||||
|
||||
=== Peak Throughput Test ===
|
||||
2025/11/22 19:13:46 WARN: Failed to load embedded library from /tmp/orly-libsecp256k1/libsecp256k1.so: Error relocating /tmp/orly-libsecp256k1/libsecp256k1.so: __fprintf_chk: symbol not found, falling back to system paths
|
||||
2025/11/22 19:13:46 INFO: Successfully loaded libsecp256k1 v5.0.0 from system path: libsecp256k1.so.2
|
||||
Events saved: 50000/50000 (100.0%), errors: 0
|
||||
Duration: 3.119005212s
|
||||
Events/sec: 16030.75
|
||||
Avg latency: 1.395117ms
|
||||
P90 latency: 1.905706ms
|
||||
P95 latency: 2.2327ms
|
||||
P99 latency: 3.309945ms
|
||||
Bottom 10% Avg latency: 759.404µs
|
||||
Wiping database between tests...
|
||||
RunBurstPatternTest (Badger)..
|
||||
|
||||
=== Burst Pattern Test ===
|
||||
Burst completed: 5000 events in 303.869245ms
|
||||
Burst completed: 5000 events in 306.183047ms
|
||||
Burst completed: 5000 events in 276.458606ms
|
||||
Burst completed: 5000 events in 304.076404ms
|
||||
Burst completed: 5000 events in 307.511965ms
|
||||
Burst completed: 5000 events in 369.956481ms
|
||||
Burst completed: 5000 events in 307.122565ms
|
||||
Burst completed: 5000 events in 282.994622ms
|
||||
Burst completed: 5000 events in 288.818591ms
|
||||
Burst completed: 5000 events in 285.099724ms
|
||||
Burst test completed: 50000 events in 8.036803222s, errors: 0
|
||||
Events/sec: 6221.38
|
||||
Wiping database between tests...
|
||||
RunMixedReadWriteTest (Badger)..
|
||||
|
||||
=== Mixed Read/Write Test ===
|
||||
Generating 1000 unique synthetic events (minimum 300 bytes each)...
|
||||
Generated 1000 events:
|
||||
Average content size: 312 bytes
|
||||
All events are unique (incremental timestamps)
|
||||
All events are properly signed
|
||||
|
||||
Pre-populating database for read tests...
|
||||
Generating 50000 unique synthetic events (minimum 300 bytes each)...
|
||||
Generated 50000 events:
|
||||
Average content size: 314 bytes
|
||||
All events are unique (incremental timestamps)
|
||||
All events are properly signed
|
||||
|
||||
Mixed test completed: 25000 writes, 25000 reads in 24.499088429s
|
||||
Combined ops/sec: 2040.89
|
||||
Wiping database between tests...
|
||||
RunQueryTest (Badger)..
|
||||
|
||||
=== Query Test ===
|
||||
Generating 10000 unique synthetic events (minimum 300 bytes each)...
|
||||
Generated 10000 events:
|
||||
Average content size: 313 bytes
|
||||
All events are unique (incremental timestamps)
|
||||
All events are properly signed
|
||||
|
||||
Pre-populating database with 10000 events for query tests...
|
||||
Query test completed: 382175 queries in 1m0.005131728s
|
||||
Queries/sec: 6369.04
|
||||
Avg query latency: 1.76377ms
|
||||
P95 query latency: 7.181013ms
|
||||
P99 query latency: 11.361846ms
|
||||
Wiping database between tests...
|
||||
RunConcurrentQueryStoreTest (Badger)..
|
||||
|
||||
=== Concurrent Query/Store Test ===
|
||||
Generating 5000 unique synthetic events (minimum 300 bytes each)...
|
||||
Generated 5000 events:
|
||||
Average content size: 313 bytes
|
||||
All events are unique (incremental timestamps)
|
||||
All events are properly signed
|
||||
|
||||
Pre-populating database with 5000 events for concurrent query/store test...
|
||||
Generating 50000 unique synthetic events (minimum 300 bytes each)...
|
||||
Generated 50000 events:
|
||||
Average content size: 314 bytes
|
||||
All events are unique (incremental timestamps)
|
||||
All events are properly signed
|
||||
|
||||
Concurrent test completed: 304137 operations (254137 queries, 50000 writes) in 1m0.003447398s
|
||||
Operations/sec: 5068.66
|
||||
Avg latency: 1.531621ms
|
||||
Avg query latency: 1.527187ms
|
||||
Avg write latency: 1.554157ms
|
||||
P95 latency: 4.058867ms
|
||||
P99 latency: 6.578532ms
|
||||
|
||||
=== Badger benchmark completed ===
|
||||
|
||||
|
||||
================================================================================
|
||||
BENCHMARK REPORT
|
||||
================================================================================
|
||||
|
||||
Test: Peak Throughput
|
||||
Duration: 3.119005212s
|
||||
Total Events: 50000
|
||||
Events/sec: 16030.75
|
||||
Success Rate: 100.0%
|
||||
Concurrent Workers: 24
|
||||
Memory Used: 90 MB
|
||||
Avg Latency: 1.395117ms
|
||||
P90 Latency: 1.905706ms
|
||||
P95 Latency: 2.2327ms
|
||||
P99 Latency: 3.309945ms
|
||||
Bottom 10% Avg Latency: 759.404µs
|
||||
----------------------------------------
|
||||
|
||||
Test: Burst Pattern
|
||||
Duration: 8.036803222s
|
||||
Total Events: 50000
|
||||
Events/sec: 6221.38
|
||||
Success Rate: 100.0%
|
||||
Concurrent Workers: 24
|
||||
Memory Used: 201 MB
|
||||
Avg Latency: 1.256755ms
|
||||
P90 Latency: 1.81348ms
|
||||
P95 Latency: 2.095959ms
|
||||
P99 Latency: 3.000094ms
|
||||
Bottom 10% Avg Latency: 457.006µs
|
||||
----------------------------------------
|
||||
|
||||
Test: Mixed Read/Write
|
||||
Duration: 24.499088429s
|
||||
Total Events: 50000
|
||||
Events/sec: 2040.89
|
||||
Success Rate: 100.0%
|
||||
Concurrent Workers: 24
|
||||
Memory Used: 174 MB
|
||||
Avg Latency: 381.925µs
|
||||
P90 Latency: 793.654µs
|
||||
P95 Latency: 890.448µs
|
||||
P99 Latency: 1.114536ms
|
||||
Bottom 10% Avg Latency: 1.055638ms
|
||||
----------------------------------------
|
||||
|
||||
Test: Query Performance
|
||||
Duration: 1m0.005131728s
|
||||
Total Events: 382175
|
||||
Events/sec: 6369.04
|
||||
Success Rate: 100.0%
|
||||
Concurrent Workers: 24
|
||||
Memory Used: 145 MB
|
||||
Avg Latency: 1.76377ms
|
||||
P90 Latency: 5.387866ms
|
||||
P95 Latency: 7.181013ms
|
||||
P99 Latency: 11.361846ms
|
||||
Bottom 10% Avg Latency: 8.012278ms
|
||||
----------------------------------------
|
||||
|
||||
Test: Concurrent Query/Store
|
||||
Duration: 1m0.003447398s
|
||||
Total Events: 304137
|
||||
Events/sec: 5068.66
|
||||
Success Rate: 100.0%
|
||||
Concurrent Workers: 24
|
||||
Memory Used: 88 MB
|
||||
Avg Latency: 1.531621ms
|
||||
P90 Latency: 3.143653ms
|
||||
P95 Latency: 4.058867ms
|
||||
P99 Latency: 6.578532ms
|
||||
Bottom 10% Avg Latency: 4.628862ms
|
||||
----------------------------------------
|
||||
|
||||
Report saved to: /tmp/benchmark_next-orly-dgraph_8/benchmark_report.txt
|
||||
AsciiDoc report saved to: /tmp/benchmark_next-orly-dgraph_8/benchmark_report.adoc
|
||||
|
||||
RELAY_NAME: next-orly-dgraph
|
||||
RELAY_URL: ws://next-orly-dgraph:8080
|
||||
TEST_TIMESTAMP: 2025-11-22T19:17:03+00:00
|
||||
BENCHMARK_CONFIG:
|
||||
Events: 50000
|
||||
Workers: 24
|
||||
Duration: 60s
|
||||
@@ -0,0 +1,198 @@
|
||||
Starting Nostr Relay Benchmark (Badger Backend)
|
||||
Data Directory: /tmp/benchmark_next-orly-neo4j_8
|
||||
Events: 50000, Workers: 24, Duration: 1m0s
|
||||
1763839028914848ℹ️ migrating to version 1... /build/pkg/database/migrations.go:66
|
||||
1763839028914921ℹ️ migrating to version 2... /build/pkg/database/migrations.go:73
|
||||
1763839028914942ℹ️ migrating to version 3... /build/pkg/database/migrations.go:80
|
||||
1763839028914948ℹ️ cleaning up ephemeral events (kinds 20000-29999)... /build/pkg/database/migrations.go:294
|
||||
1763839028914958ℹ️ cleaned up 0 ephemeral events from database /build/pkg/database/migrations.go:339
|
||||
1763839028914973ℹ️ migrating to version 4... /build/pkg/database/migrations.go:87
|
||||
1763839028914989ℹ️ converting events to optimized inline storage (Reiser4 optimization)... /build/pkg/database/migrations.go:347
|
||||
1763839028915007ℹ️ found 0 events to convert (0 regular, 0 replaceable, 0 addressable) /build/pkg/database/migrations.go:436
|
||||
1763839028915013ℹ️ migration complete: converted 0 events to optimized inline storage, deleted 0 old keys /build/pkg/database/migrations.go:545
|
||||
1763839028915036ℹ️ migrating to version 5... /build/pkg/database/migrations.go:94
|
||||
1763839028915041ℹ️ re-encoding events with optimized tag binary format... /build/pkg/database/migrations.go:552
|
||||
1763839028915050ℹ️ found 0 events with e/p tags to re-encode /build/pkg/database/migrations.go:639
|
||||
1763839028915055ℹ️ no events need re-encoding /build/pkg/database/migrations.go:642
|
||||
|
||||
╔════════════════════════════════════════════════════════╗
|
||||
║ BADGER BACKEND BENCHMARK SUITE ║
|
||||
╚════════════════════════════════════════════════════════╝
|
||||
|
||||
=== Starting Badger benchmark ===
|
||||
RunPeakThroughputTest (Badger)..
|
||||
|
||||
=== Peak Throughput Test ===
|
||||
2025/11/22 19:17:08 WARN: Failed to load embedded library from /tmp/orly-libsecp256k1/libsecp256k1.so: Error relocating /tmp/orly-libsecp256k1/libsecp256k1.so: __fprintf_chk: symbol not found, falling back to system paths
|
||||
2025/11/22 19:17:08 INFO: Successfully loaded libsecp256k1 v5.0.0 from system path: libsecp256k1.so.2
|
||||
Events saved: 50000/50000 (100.0%), errors: 0
|
||||
Duration: 3.018399124s
|
||||
Events/sec: 16565.07
|
||||
Avg latency: 1.32858ms
|
||||
P90 latency: 1.828555ms
|
||||
P95 latency: 2.11453ms
|
||||
P99 latency: 2.990871ms
|
||||
Bottom 10% Avg latency: 724.65µs
|
||||
Wiping database between tests...
|
||||
RunBurstPatternTest (Badger)..
|
||||
|
||||
=== Burst Pattern Test ===
|
||||
Burst completed: 5000 events in 293.405025ms
|
||||
Burst completed: 5000 events in 361.620316ms
|
||||
Burst completed: 5000 events in 345.575904ms
|
||||
Burst completed: 5000 events in 316.292611ms
|
||||
Burst completed: 5000 events in 295.528334ms
|
||||
Burst completed: 5000 events in 358.255713ms
|
||||
Burst completed: 5000 events in 442.869494ms
|
||||
Burst completed: 5000 events in 301.13784ms
|
||||
Burst completed: 5000 events in 284.850497ms
|
||||
Burst completed: 5000 events in 291.965255ms
|
||||
Burst test completed: 50000 events in 8.29667615s, errors: 0
|
||||
Events/sec: 6026.51
|
||||
Wiping database between tests...
|
||||
RunMixedReadWriteTest (Badger)..
|
||||
|
||||
=== Mixed Read/Write Test ===
|
||||
Generating 1000 unique synthetic events (minimum 300 bytes each)...
|
||||
Generated 1000 events:
|
||||
Average content size: 312 bytes
|
||||
All events are unique (incremental timestamps)
|
||||
All events are properly signed
|
||||
|
||||
Pre-populating database for read tests...
|
||||
Generating 50000 unique synthetic events (minimum 300 bytes each)...
|
||||
Generated 50000 events:
|
||||
Average content size: 314 bytes
|
||||
All events are unique (incremental timestamps)
|
||||
All events are properly signed
|
||||
|
||||
Mixed test completed: 25000 writes, 25000 reads in 24.529156295s
|
||||
Combined ops/sec: 2038.39
|
||||
Wiping database between tests...
|
||||
RunQueryTest (Badger)..
|
||||
|
||||
=== Query Test ===
|
||||
Generating 10000 unique synthetic events (minimum 300 bytes each)...
|
||||
Generated 10000 events:
|
||||
Average content size: 313 bytes
|
||||
All events are unique (incremental timestamps)
|
||||
All events are properly signed
|
||||
|
||||
Pre-populating database with 10000 events for query tests...
|
||||
Query test completed: 397591 queries in 1m0.004044242s
|
||||
Queries/sec: 6626.07
|
||||
Avg query latency: 1.67631ms
|
||||
P95 query latency: 6.658216ms
|
||||
P99 query latency: 10.435254ms
|
||||
Wiping database between tests...
|
||||
RunConcurrentQueryStoreTest (Badger)..
|
||||
|
||||
=== Concurrent Query/Store Test ===
|
||||
Generating 5000 unique synthetic events (minimum 300 bytes each)...
|
||||
Generated 5000 events:
|
||||
Average content size: 313 bytes
|
||||
All events are unique (incremental timestamps)
|
||||
All events are properly signed
|
||||
|
||||
Pre-populating database with 5000 events for concurrent query/store test...
|
||||
Generating 50000 unique synthetic events (minimum 300 bytes each)...
|
||||
Generated 50000 events:
|
||||
Average content size: 314 bytes
|
||||
All events are unique (incremental timestamps)
|
||||
All events are properly signed
|
||||
|
||||
Concurrent test completed: 312697 operations (262697 queries, 50000 writes) in 1m0.003549163s
|
||||
Operations/sec: 5211.31
|
||||
Avg latency: 1.489002ms
|
||||
Avg query latency: 1.46537ms
|
||||
Avg write latency: 1.613163ms
|
||||
P95 latency: 3.830988ms
|
||||
P99 latency: 6.471326ms
|
||||
|
||||
=== Badger benchmark completed ===
|
||||
|
||||
|
||||
================================================================================
|
||||
BENCHMARK REPORT
|
||||
================================================================================
|
||||
|
||||
Test: Peak Throughput
|
||||
Duration: 3.018399124s
|
||||
Total Events: 50000
|
||||
Events/sec: 16565.07
|
||||
Success Rate: 100.0%
|
||||
Concurrent Workers: 24
|
||||
Memory Used: 204 MB
|
||||
Avg Latency: 1.32858ms
|
||||
P90 Latency: 1.828555ms
|
||||
P95 Latency: 2.11453ms
|
||||
P99 Latency: 2.990871ms
|
||||
Bottom 10% Avg Latency: 724.65µs
|
||||
----------------------------------------
|
||||
|
||||
Test: Burst Pattern
|
||||
Duration: 8.29667615s
|
||||
Total Events: 50000
|
||||
Events/sec: 6026.51
|
||||
Success Rate: 100.0%
|
||||
Concurrent Workers: 24
|
||||
Memory Used: 205 MB
|
||||
Avg Latency: 1.392811ms
|
||||
P90 Latency: 2.088531ms
|
||||
P95 Latency: 2.568976ms
|
||||
P99 Latency: 4.193773ms
|
||||
Bottom 10% Avg Latency: 462.345µs
|
||||
----------------------------------------
|
||||
|
||||
Test: Mixed Read/Write
|
||||
Duration: 24.529156295s
|
||||
Total Events: 50000
|
||||
Events/sec: 2038.39
|
||||
Success Rate: 100.0%
|
||||
Concurrent Workers: 24
|
||||
Memory Used: 132 MB
|
||||
Avg Latency: 388.158µs
|
||||
P90 Latency: 813.891µs
|
||||
P95 Latency: 910.826µs
|
||||
P99 Latency: 1.152085ms
|
||||
Bottom 10% Avg Latency: 1.025153ms
|
||||
----------------------------------------
|
||||
|
||||
Test: Query Performance
|
||||
Duration: 1m0.004044242s
|
||||
Total Events: 397591
|
||||
Events/sec: 6626.07
|
||||
Success Rate: 100.0%
|
||||
Concurrent Workers: 24
|
||||
Memory Used: 116 MB
|
||||
Avg Latency: 1.67631ms
|
||||
P90 Latency: 5.072074ms
|
||||
P95 Latency: 6.658216ms
|
||||
P99 Latency: 10.435254ms
|
||||
Bottom 10% Avg Latency: 7.422142ms
|
||||
----------------------------------------
|
||||
|
||||
Test: Concurrent Query/Store
|
||||
Duration: 1m0.003549163s
|
||||
Total Events: 312697
|
||||
Events/sec: 5211.31
|
||||
Success Rate: 100.0%
|
||||
Concurrent Workers: 24
|
||||
Memory Used: 139 MB
|
||||
Avg Latency: 1.489002ms
|
||||
P90 Latency: 2.962995ms
|
||||
P95 Latency: 3.830988ms
|
||||
P99 Latency: 6.471326ms
|
||||
Bottom 10% Avg Latency: 4.527291ms
|
||||
----------------------------------------
|
||||
|
||||
Report saved to: /tmp/benchmark_next-orly-neo4j_8/benchmark_report.txt
|
||||
AsciiDoc report saved to: /tmp/benchmark_next-orly-neo4j_8/benchmark_report.adoc
|
||||
|
||||
RELAY_NAME: next-orly-neo4j
|
||||
RELAY_URL: ws://next-orly-neo4j:8080
|
||||
TEST_TIMESTAMP: 2025-11-22T19:20:26+00:00
|
||||
BENCHMARK_CONFIG:
|
||||
Events: 50000
|
||||
Workers: 24
|
||||
Duration: 60s
|
||||
@@ -0,0 +1,198 @@
|
||||
Starting Nostr Relay Benchmark (Badger Backend)
|
||||
Data Directory: /tmp/benchmark_nostr-rs-relay_8
|
||||
Events: 50000, Workers: 24, Duration: 1m0s
|
||||
1763840044071805ℹ️ migrating to version 1... /build/pkg/database/migrations.go:66
|
||||
1763840044071886ℹ️ migrating to version 2... /build/pkg/database/migrations.go:73
|
||||
1763840044071912ℹ️ migrating to version 3... /build/pkg/database/migrations.go:80
|
||||
1763840044071918ℹ️ cleaning up ephemeral events (kinds 20000-29999)... /build/pkg/database/migrations.go:294
|
||||
1763840044071926ℹ️ cleaned up 0 ephemeral events from database /build/pkg/database/migrations.go:339
|
||||
1763840044071941ℹ️ migrating to version 4... /build/pkg/database/migrations.go:87
|
||||
1763840044071946ℹ️ converting events to optimized inline storage (Reiser4 optimization)... /build/pkg/database/migrations.go:347
|
||||
1763840044071959ℹ️ found 0 events to convert (0 regular, 0 replaceable, 0 addressable) /build/pkg/database/migrations.go:436
|
||||
1763840044071965ℹ️ migration complete: converted 0 events to optimized inline storage, deleted 0 old keys /build/pkg/database/migrations.go:545
|
||||
1763840044071993ℹ️ migrating to version 5... /build/pkg/database/migrations.go:94
|
||||
1763840044072003ℹ️ re-encoding events with optimized tag binary format... /build/pkg/database/migrations.go:552
|
||||
1763840044072012ℹ️ found 0 events with e/p tags to re-encode /build/pkg/database/migrations.go:639
|
||||
1763840044072017ℹ️ no events need re-encoding /build/pkg/database/migrations.go:642
|
||||
|
||||
╔════════════════════════════════════════════════════════╗
|
||||
║ BADGER BACKEND BENCHMARK SUITE ║
|
||||
╚════════════════════════════════════════════════════════╝
|
||||
|
||||
=== Starting Badger benchmark ===
|
||||
RunPeakThroughputTest (Badger)..
|
||||
|
||||
=== Peak Throughput Test ===
|
||||
2025/11/22 19:34:04 WARN: Failed to load embedded library from /tmp/orly-libsecp256k1/libsecp256k1.so: Error relocating /tmp/orly-libsecp256k1/libsecp256k1.so: __fprintf_chk: symbol not found, falling back to system paths
|
||||
2025/11/22 19:34:04 INFO: Successfully loaded libsecp256k1 v5.0.0 from system path: libsecp256k1.so.2
|
||||
Events saved: 50000/50000 (100.0%), errors: 0
|
||||
Duration: 3.370139282s
|
||||
Events/sec: 14836.18
|
||||
Avg latency: 1.545053ms
|
||||
P90 latency: 2.163496ms
|
||||
P95 latency: 2.562666ms
|
||||
P99 latency: 3.871045ms
|
||||
Bottom 10% Avg latency: 829.94µs
|
||||
Wiping database between tests...
|
||||
RunBurstPatternTest (Badger)..
|
||||
|
||||
=== Burst Pattern Test ===
|
||||
Burst completed: 5000 events in 291.316304ms
|
||||
Burst completed: 5000 events in 318.38321ms
|
||||
Burst completed: 5000 events in 369.717856ms
|
||||
Burst completed: 5000 events in 386.679947ms
|
||||
Burst completed: 5000 events in 313.894228ms
|
||||
Burst completed: 5000 events in 375.7593ms
|
||||
Burst completed: 5000 events in 300.682893ms
|
||||
Burst completed: 5000 events in 270.421689ms
|
||||
Burst completed: 5000 events in 281.989788ms
|
||||
Burst completed: 5000 events in 265.54975ms
|
||||
Burst test completed: 50000 events in 8.181579562s, errors: 0
|
||||
Events/sec: 6111.29
|
||||
Wiping database between tests...
|
||||
RunMixedReadWriteTest (Badger)..
|
||||
|
||||
=== Mixed Read/Write Test ===
|
||||
Generating 1000 unique synthetic events (minimum 300 bytes each)...
|
||||
Generated 1000 events:
|
||||
Average content size: 312 bytes
|
||||
All events are unique (incremental timestamps)
|
||||
All events are properly signed
|
||||
|
||||
Pre-populating database for read tests...
|
||||
Generating 50000 unique synthetic events (minimum 300 bytes each)...
|
||||
Generated 50000 events:
|
||||
Average content size: 314 bytes
|
||||
All events are unique (incremental timestamps)
|
||||
All events are properly signed
|
||||
|
||||
Mixed test completed: 25000 writes, 25000 reads in 24.611048938s
|
||||
Combined ops/sec: 2031.61
|
||||
Wiping database between tests...
|
||||
RunQueryTest (Badger)..
|
||||
|
||||
=== Query Test ===
|
||||
Generating 10000 unique synthetic events (minimum 300 bytes each)...
|
||||
Generated 10000 events:
|
||||
Average content size: 313 bytes
|
||||
All events are unique (incremental timestamps)
|
||||
All events are properly signed
|
||||
|
||||
Pre-populating database with 10000 events for query tests...
|
||||
Query test completed: 388576 queries in 1m0.007765782s
|
||||
Queries/sec: 6475.43
|
||||
Avg query latency: 1.737292ms
|
||||
P95 query latency: 7.011739ms
|
||||
P99 query latency: 11.25404ms
|
||||
Wiping database between tests...
|
||||
RunConcurrentQueryStoreTest (Badger)..
|
||||
|
||||
=== Concurrent Query/Store Test ===
|
||||
Generating 5000 unique synthetic events (minimum 300 bytes each)...
|
||||
Generated 5000 events:
|
||||
Average content size: 313 bytes
|
||||
All events are unique (incremental timestamps)
|
||||
All events are properly signed
|
||||
|
||||
Pre-populating database with 5000 events for concurrent query/store test...
|
||||
Generating 50000 unique synthetic events (minimum 300 bytes each)...
|
||||
Generated 50000 events:
|
||||
Average content size: 314 bytes
|
||||
All events are unique (incremental timestamps)
|
||||
All events are properly signed
|
||||
|
||||
Concurrent test completed: 320770 operations (270770 queries, 50000 writes) in 1m0.003815149s
|
||||
Operations/sec: 5345.83
|
||||
Avg latency: 1.418636ms
|
||||
Avg query latency: 1.407911ms
|
||||
Avg write latency: 1.476716ms
|
||||
P95 latency: 3.545655ms
|
||||
P99 latency: 5.727035ms
|
||||
|
||||
=== Badger benchmark completed ===
|
||||
|
||||
|
||||
================================================================================
|
||||
BENCHMARK REPORT
|
||||
================================================================================
|
||||
|
||||
Test: Peak Throughput
|
||||
Duration: 3.370139282s
|
||||
Total Events: 50000
|
||||
Events/sec: 14836.18
|
||||
Success Rate: 100.0%
|
||||
Concurrent Workers: 24
|
||||
Memory Used: 131 MB
|
||||
Avg Latency: 1.545053ms
|
||||
P90 Latency: 2.163496ms
|
||||
P95 Latency: 2.562666ms
|
||||
P99 Latency: 3.871045ms
|
||||
Bottom 10% Avg Latency: 829.94µs
|
||||
----------------------------------------
|
||||
|
||||
Test: Burst Pattern
|
||||
Duration: 8.181579562s
|
||||
Total Events: 50000
|
||||
Events/sec: 6111.29
|
||||
Success Rate: 100.0%
|
||||
Concurrent Workers: 24
|
||||
Memory Used: 205 MB
|
||||
Avg Latency: 1.336805ms
|
||||
P90 Latency: 2.051133ms
|
||||
P95 Latency: 2.417039ms
|
||||
P99 Latency: 3.368018ms
|
||||
Bottom 10% Avg Latency: 499.404µs
|
||||
----------------------------------------
|
||||
|
||||
Test: Mixed Read/Write
|
||||
Duration: 24.611048938s
|
||||
Total Events: 50000
|
||||
Events/sec: 2031.61
|
||||
Success Rate: 100.0%
|
||||
Concurrent Workers: 24
|
||||
Memory Used: 112 MB
|
||||
Avg Latency: 397.462µs
|
||||
P90 Latency: 827.995µs
|
||||
P95 Latency: 936.832µs
|
||||
P99 Latency: 1.2249ms
|
||||
Bottom 10% Avg Latency: 1.08713ms
|
||||
----------------------------------------
|
||||
|
||||
Test: Query Performance
|
||||
Duration: 1m0.007765782s
|
||||
Total Events: 388576
|
||||
Events/sec: 6475.43
|
||||
Success Rate: 100.0%
|
||||
Concurrent Workers: 24
|
||||
Memory Used: 117 MB
|
||||
Avg Latency: 1.737292ms
|
||||
P90 Latency: 5.250359ms
|
||||
P95 Latency: 7.011739ms
|
||||
P99 Latency: 11.25404ms
|
||||
Bottom 10% Avg Latency: 7.872769ms
|
||||
----------------------------------------
|
||||
|
||||
Test: Concurrent Query/Store
|
||||
Duration: 1m0.003815149s
|
||||
Total Events: 320770
|
||||
Events/sec: 5345.83
|
||||
Success Rate: 100.0%
|
||||
Concurrent Workers: 24
|
||||
Memory Used: 112 MB
|
||||
Avg Latency: 1.418636ms
|
||||
P90 Latency: 2.830856ms
|
||||
P95 Latency: 3.545655ms
|
||||
P99 Latency: 5.727035ms
|
||||
Bottom 10% Avg Latency: 4.081447ms
|
||||
----------------------------------------
|
||||
|
||||
Report saved to: /tmp/benchmark_nostr-rs-relay_8/benchmark_report.txt
|
||||
AsciiDoc report saved to: /tmp/benchmark_nostr-rs-relay_8/benchmark_report.adoc
|
||||
|
||||
RELAY_NAME: nostr-rs-relay
|
||||
RELAY_URL: ws://nostr-rs-relay:8080
|
||||
TEST_TIMESTAMP: 2025-11-22T19:37:22+00:00
|
||||
BENCHMARK_CONFIG:
|
||||
Events: 50000
|
||||
Workers: 24
|
||||
Duration: 60s
|
||||
@@ -0,0 +1,198 @@
|
||||
Starting Nostr Relay Benchmark (Badger Backend)
|
||||
Data Directory: /tmp/benchmark_relayer-basic_8
|
||||
Events: 50000, Workers: 24, Duration: 1m0s
|
||||
1763839638031581ℹ️ migrating to version 1... /build/pkg/database/migrations.go:66
|
||||
1763839638031660ℹ️ migrating to version 2... /build/pkg/database/migrations.go:73
|
||||
1763839638031685ℹ️ migrating to version 3... /build/pkg/database/migrations.go:80
|
||||
1763839638031691ℹ️ cleaning up ephemeral events (kinds 20000-29999)... /build/pkg/database/migrations.go:294
|
||||
1763839638031697ℹ️ cleaned up 0 ephemeral events from database /build/pkg/database/migrations.go:339
|
||||
1763839638031717ℹ️ migrating to version 4... /build/pkg/database/migrations.go:87
|
||||
1763839638031722ℹ️ converting events to optimized inline storage (Reiser4 optimization)... /build/pkg/database/migrations.go:347
|
||||
1763839638031734ℹ️ found 0 events to convert (0 regular, 0 replaceable, 0 addressable) /build/pkg/database/migrations.go:436
|
||||
1763839638031740ℹ️ migration complete: converted 0 events to optimized inline storage, deleted 0 old keys /build/pkg/database/migrations.go:545
|
||||
1763839638031756ℹ️ migrating to version 5... /build/pkg/database/migrations.go:94
|
||||
1763839638031761ℹ️ re-encoding events with optimized tag binary format... /build/pkg/database/migrations.go:552
|
||||
1763839638031770ℹ️ found 0 events with e/p tags to re-encode /build/pkg/database/migrations.go:639
|
||||
1763839638031775ℹ️ no events need re-encoding /build/pkg/database/migrations.go:642
|
||||
|
||||
╔════════════════════════════════════════════════════════╗
|
||||
║ BADGER BACKEND BENCHMARK SUITE ║
|
||||
╚════════════════════════════════════════════════════════╝
|
||||
|
||||
=== Starting Badger benchmark ===
|
||||
RunPeakThroughputTest (Badger)..
|
||||
|
||||
=== Peak Throughput Test ===
|
||||
2025/11/22 19:27:18 WARN: Failed to load embedded library from /tmp/orly-libsecp256k1/libsecp256k1.so: Error relocating /tmp/orly-libsecp256k1/libsecp256k1.so: __fprintf_chk: symbol not found, falling back to system paths
|
||||
2025/11/22 19:27:18 INFO: Successfully loaded libsecp256k1 v5.0.0 from system path: libsecp256k1.so.2
|
||||
Events saved: 50000/50000 (100.0%), errors: 0
|
||||
Duration: 3.316457481s
|
||||
Events/sec: 15076.33
|
||||
Avg latency: 1.517087ms
|
||||
P90 latency: 2.134693ms
|
||||
P95 latency: 2.48546ms
|
||||
P99 latency: 3.572901ms
|
||||
Bottom 10% Avg latency: 821.229µs
|
||||
Wiping database between tests...
|
||||
RunBurstPatternTest (Badger)..
|
||||
|
||||
=== Burst Pattern Test ===
|
||||
Burst completed: 5000 events in 276.700297ms
|
||||
Burst completed: 5000 events in 392.081438ms
|
||||
Burst completed: 5000 events in 314.563405ms
|
||||
Burst completed: 5000 events in 397.214306ms
|
||||
Burst completed: 5000 events in 322.96797ms
|
||||
Burst completed: 5000 events in 373.044665ms
|
||||
Burst completed: 5000 events in 296.191438ms
|
||||
Burst completed: 5000 events in 271.613902ms
|
||||
Burst completed: 5000 events in 287.329791ms
|
||||
Burst completed: 5000 events in 296.745792ms
|
||||
Burst test completed: 50000 events in 8.234927616s, errors: 0
|
||||
Events/sec: 6071.70
|
||||
Wiping database between tests...
|
||||
RunMixedReadWriteTest (Badger)..
|
||||
|
||||
=== Mixed Read/Write Test ===
|
||||
Generating 1000 unique synthetic events (minimum 300 bytes each)...
|
||||
Generated 1000 events:
|
||||
Average content size: 312 bytes
|
||||
All events are unique (incremental timestamps)
|
||||
All events are properly signed
|
||||
|
||||
Pre-populating database for read tests...
|
||||
Generating 50000 unique synthetic events (minimum 300 bytes each)...
|
||||
Generated 50000 events:
|
||||
Average content size: 314 bytes
|
||||
All events are unique (incremental timestamps)
|
||||
All events are properly signed
|
||||
|
||||
Mixed test completed: 25000 writes, 25000 reads in 24.561126307s
|
||||
Combined ops/sec: 2035.74
|
||||
Wiping database between tests...
|
||||
RunQueryTest (Badger)..
|
||||
|
||||
=== Query Test ===
|
||||
Generating 10000 unique synthetic events (minimum 300 bytes each)...
|
||||
Generated 10000 events:
|
||||
Average content size: 313 bytes
|
||||
All events are unique (incremental timestamps)
|
||||
All events are properly signed
|
||||
|
||||
Pre-populating database with 10000 events for query tests...
|
||||
Query test completed: 382011 queries in 1m0.004538365s
|
||||
Queries/sec: 6366.37
|
||||
Avg query latency: 1.775143ms
|
||||
P95 query latency: 7.266438ms
|
||||
P99 query latency: 11.395836ms
|
||||
Wiping database between tests...
|
||||
RunConcurrentQueryStoreTest (Badger)..
|
||||
|
||||
=== Concurrent Query/Store Test ===
|
||||
Generating 5000 unique synthetic events (minimum 300 bytes each)...
|
||||
Generated 5000 events:
|
||||
Average content size: 313 bytes
|
||||
All events are unique (incremental timestamps)
|
||||
All events are properly signed
|
||||
|
||||
Pre-populating database with 5000 events for concurrent query/store test...
|
||||
Generating 50000 unique synthetic events (minimum 300 bytes each)...
|
||||
Generated 50000 events:
|
||||
Average content size: 314 bytes
|
||||
All events are unique (incremental timestamps)
|
||||
All events are properly signed
|
||||
|
||||
Concurrent test completed: 315099 operations (265099 queries, 50000 writes) in 1m0.002672022s
|
||||
Operations/sec: 5251.42
|
||||
Avg latency: 1.462691ms
|
||||
Avg query latency: 1.440796ms
|
||||
Avg write latency: 1.578778ms
|
||||
P95 latency: 3.739636ms
|
||||
P99 latency: 6.381464ms
|
||||
|
||||
=== Badger benchmark completed ===
|
||||
|
||||
|
||||
================================================================================
|
||||
BENCHMARK REPORT
|
||||
================================================================================
|
||||
|
||||
Test: Peak Throughput
|
||||
Duration: 3.316457481s
|
||||
Total Events: 50000
|
||||
Events/sec: 15076.33
|
||||
Success Rate: 100.0%
|
||||
Concurrent Workers: 24
|
||||
Memory Used: 133 MB
|
||||
Avg Latency: 1.517087ms
|
||||
P90 Latency: 2.134693ms
|
||||
P95 Latency: 2.48546ms
|
||||
P99 Latency: 3.572901ms
|
||||
Bottom 10% Avg Latency: 821.229µs
|
||||
----------------------------------------
|
||||
|
||||
Test: Burst Pattern
|
||||
Duration: 8.234927616s
|
||||
Total Events: 50000
|
||||
Events/sec: 6071.70
|
||||
Success Rate: 100.0%
|
||||
Concurrent Workers: 24
|
||||
Memory Used: 186 MB
|
||||
Avg Latency: 1.385607ms
|
||||
P90 Latency: 2.08644ms
|
||||
P95 Latency: 2.478156ms
|
||||
P99 Latency: 3.769153ms
|
||||
Bottom 10% Avg Latency: 520.086µs
|
||||
----------------------------------------
|
||||
|
||||
Test: Mixed Read/Write
|
||||
Duration: 24.561126307s
|
||||
Total Events: 50000
|
||||
Events/sec: 2035.74
|
||||
Success Rate: 100.0%
|
||||
Concurrent Workers: 24
|
||||
Memory Used: 177 MB
|
||||
Avg Latency: 394.452µs
|
||||
P90 Latency: 821.172µs
|
||||
P95 Latency: 916.474µs
|
||||
P99 Latency: 1.143807ms
|
||||
Bottom 10% Avg Latency: 1.056519ms
|
||||
----------------------------------------
|
||||
|
||||
Test: Query Performance
|
||||
Duration: 1m0.004538365s
|
||||
Total Events: 382011
|
||||
Events/sec: 6366.37
|
||||
Success Rate: 100.0%
|
||||
Concurrent Workers: 24
|
||||
Memory Used: 134 MB
|
||||
Avg Latency: 1.775143ms
|
||||
P90 Latency: 5.448168ms
|
||||
P95 Latency: 7.266438ms
|
||||
P99 Latency: 11.395836ms
|
||||
Bottom 10% Avg Latency: 8.059404ms
|
||||
----------------------------------------
|
||||
|
||||
Test: Concurrent Query/Store
|
||||
Duration: 1m0.002672022s
|
||||
Total Events: 315099
|
||||
Events/sec: 5251.42
|
||||
Success Rate: 100.0%
|
||||
Concurrent Workers: 24
|
||||
Memory Used: 107 MB
|
||||
Avg Latency: 1.462691ms
|
||||
P90 Latency: 2.897052ms
|
||||
P95 Latency: 3.739636ms
|
||||
P99 Latency: 6.381464ms
|
||||
Bottom 10% Avg Latency: 4.413874ms
|
||||
----------------------------------------
|
||||
|
||||
Report saved to: /tmp/benchmark_relayer-basic_8/benchmark_report.txt
|
||||
AsciiDoc report saved to: /tmp/benchmark_relayer-basic_8/benchmark_report.adoc
|
||||
|
||||
RELAY_NAME: relayer-basic
|
||||
RELAY_URL: ws://relayer-basic:7447
|
||||
TEST_TIMESTAMP: 2025-11-22T19:30:36+00:00
|
||||
BENCHMARK_CONFIG:
|
||||
Events: 50000
|
||||
Workers: 24
|
||||
Duration: 60s
|
||||
@@ -0,0 +1,199 @@
|
||||
Starting Nostr Relay Benchmark (Badger Backend)
|
||||
Data Directory: /tmp/benchmark_rely-sqlite_8
|
||||
Events: 50000, Workers: 24, Duration: 1m0s
|
||||
1763838420592113ℹ️ migrating to version 1... /build/pkg/database/migrations.go:66
|
||||
1763838420592185ℹ️ migrating to version 2... /build/pkg/database/migrations.go:73
|
||||
1763838420592206ℹ️ migrating to version 3... /build/pkg/database/migrations.go:80
|
||||
1763838420592211ℹ️ cleaning up ephemeral events (kinds 20000-29999)... /build/pkg/database/migrations.go:294
|
||||
1763838420592221ℹ️ cleaned up 0 ephemeral events from database /build/pkg/database/migrations.go:339
|
||||
1763838420592244ℹ️ migrating to version 4... /build/pkg/database/migrations.go:87
|
||||
1763838420592249ℹ️ converting events to optimized inline storage (Reiser4 optimization)... /build/pkg/database/migrations.go:347
|
||||
1763838420592260ℹ️ found 0 events to convert (0 regular, 0 replaceable, 0 addressable) /build/pkg/database/migrations.go:436
|
||||
1763838420592265ℹ️ migration complete: converted 0 events to optimized inline storage, deleted 0 old keys /build/pkg/database/migrations.go:545
|
||||
1763838420592279ℹ️ migrating to version 5... /build/pkg/database/migrations.go:94
|
||||
1763838420592284ℹ️ re-encoding events with optimized tag binary format... /build/pkg/database/migrations.go:552
|
||||
1763838420592294ℹ️ found 0 events with e/p tags to re-encode /build/pkg/database/migrations.go:639
|
||||
1763838420592300ℹ️ no events need re-encoding /build/pkg/database/migrations.go:642
|
||||
|
||||
╔════════════════════════════════════════════════════════╗
|
||||
║ BADGER BACKEND BENCHMARK SUITE ║
|
||||
╚════════════════════════════════════════════════════════╝
|
||||
|
||||
=== Starting Badger benchmark ===
|
||||
RunPeakThroughputTest (Badger)..
|
||||
|
||||
=== Peak Throughput Test ===
|
||||
2025/11/22 19:07:00 INFO: Extracted embedded libsecp256k1 to /tmp/orly-libsecp256k1/libsecp256k1.so
|
||||
2025/11/22 19:07:00 WARN: Failed to load embedded library from /tmp/orly-libsecp256k1/libsecp256k1.so: Error relocating /tmp/orly-libsecp256k1/libsecp256k1.so: __fprintf_chk: symbol not found, falling back to system paths
|
||||
2025/11/22 19:07:00 INFO: Successfully loaded libsecp256k1 v5.0.0 from system path: libsecp256k1.so.2
|
||||
Events saved: 50000/50000 (100.0%), errors: 0
|
||||
Duration: 3.144005095s
|
||||
Events/sec: 15903.28
|
||||
Avg latency: 1.399274ms
|
||||
P90 latency: 1.969161ms
|
||||
P95 latency: 2.34974ms
|
||||
P99 latency: 3.740183ms
|
||||
Bottom 10% Avg latency: 746.992µs
|
||||
Wiping database between tests...
|
||||
RunBurstPatternTest (Badger)..
|
||||
|
||||
=== Burst Pattern Test ===
|
||||
Burst completed: 5000 events in 289.665872ms
|
||||
Burst completed: 5000 events in 298.189416ms
|
||||
Burst completed: 5000 events in 284.248905ms
|
||||
Burst completed: 5000 events in 299.878917ms
|
||||
Burst completed: 5000 events in 290.195429ms
|
||||
Burst completed: 5000 events in 335.211169ms
|
||||
Burst completed: 5000 events in 306.221225ms
|
||||
Burst completed: 5000 events in 280.945252ms
|
||||
Burst completed: 5000 events in 270.701091ms
|
||||
Burst completed: 5000 events in 265.342517ms
|
||||
Burst test completed: 50000 events in 7.925705852s, errors: 0
|
||||
Events/sec: 6308.59
|
||||
Wiping database between tests...
|
||||
RunMixedReadWriteTest (Badger)..
|
||||
|
||||
=== Mixed Read/Write Test ===
|
||||
Generating 1000 unique synthetic events (minimum 300 bytes each)...
|
||||
Generated 1000 events:
|
||||
Average content size: 312 bytes
|
||||
All events are unique (incremental timestamps)
|
||||
All events are properly signed
|
||||
|
||||
Pre-populating database for read tests...
|
||||
Generating 50000 unique synthetic events (minimum 300 bytes each)...
|
||||
Generated 50000 events:
|
||||
Average content size: 314 bytes
|
||||
All events are unique (incremental timestamps)
|
||||
All events are properly signed
|
||||
|
||||
Mixed test completed: 25000 writes, 25000 reads in 24.557413391s
|
||||
Combined ops/sec: 2036.05
|
||||
Wiping database between tests...
|
||||
RunQueryTest (Badger)..
|
||||
|
||||
=== Query Test ===
|
||||
Generating 10000 unique synthetic events (minimum 300 bytes each)...
|
||||
Generated 10000 events:
|
||||
Average content size: 313 bytes
|
||||
All events are unique (incremental timestamps)
|
||||
All events are properly signed
|
||||
|
||||
Pre-populating database with 10000 events for query tests...
|
||||
Query test completed: 388544 queries in 1m0.004756071s
|
||||
Queries/sec: 6475.22
|
||||
Avg query latency: 1.723827ms
|
||||
P95 query latency: 6.917596ms
|
||||
P99 query latency: 10.942489ms
|
||||
Wiping database between tests...
|
||||
RunConcurrentQueryStoreTest (Badger)..
|
||||
|
||||
=== Concurrent Query/Store Test ===
|
||||
Generating 5000 unique synthetic events (minimum 300 bytes each)...
|
||||
Generated 5000 events:
|
||||
Average content size: 313 bytes
|
||||
All events are unique (incremental timestamps)
|
||||
All events are properly signed
|
||||
|
||||
Pre-populating database with 5000 events for concurrent query/store test...
|
||||
Generating 50000 unique synthetic events (minimum 300 bytes each)...
|
||||
Generated 50000 events:
|
||||
Average content size: 314 bytes
|
||||
All events are unique (incremental timestamps)
|
||||
All events are properly signed
|
||||
|
||||
Concurrent test completed: 309051 operations (259051 queries, 50000 writes) in 1m0.003409818s
|
||||
Operations/sec: 5150.56
|
||||
Avg latency: 1.532079ms
|
||||
Avg query latency: 1.486246ms
|
||||
Avg write latency: 1.769539ms
|
||||
P95 latency: 4.004134ms
|
||||
P99 latency: 6.701092ms
|
||||
|
||||
=== Badger benchmark completed ===
|
||||
|
||||
|
||||
================================================================================
|
||||
BENCHMARK REPORT
|
||||
================================================================================
|
||||
|
||||
Test: Peak Throughput
|
||||
Duration: 3.144005095s
|
||||
Total Events: 50000
|
||||
Events/sec: 15903.28
|
||||
Success Rate: 100.0%
|
||||
Concurrent Workers: 24
|
||||
Memory Used: 121 MB
|
||||
Avg Latency: 1.399274ms
|
||||
P90 Latency: 1.969161ms
|
||||
P95 Latency: 2.34974ms
|
||||
P99 Latency: 3.740183ms
|
||||
Bottom 10% Avg Latency: 746.992µs
|
||||
----------------------------------------
|
||||
|
||||
Test: Burst Pattern
|
||||
Duration: 7.925705852s
|
||||
Total Events: 50000
|
||||
Events/sec: 6308.59
|
||||
Success Rate: 100.0%
|
||||
Concurrent Workers: 24
|
||||
Memory Used: 188 MB
|
||||
Avg Latency: 1.174853ms
|
||||
P90 Latency: 1.682332ms
|
||||
P95 Latency: 1.933092ms
|
||||
P99 Latency: 2.630546ms
|
||||
Bottom 10% Avg Latency: 472.317µs
|
||||
----------------------------------------
|
||||
|
||||
Test: Mixed Read/Write
|
||||
Duration: 24.557413391s
|
||||
Total Events: 50000
|
||||
Events/sec: 2036.05
|
||||
Success Rate: 100.0%
|
||||
Concurrent Workers: 24
|
||||
Memory Used: 130 MB
|
||||
Avg Latency: 385.432µs
|
||||
P90 Latency: 801.624µs
|
||||
P95 Latency: 897.528µs
|
||||
P99 Latency: 1.136145ms
|
||||
Bottom 10% Avg Latency: 1.031469ms
|
||||
----------------------------------------
|
||||
|
||||
Test: Query Performance
|
||||
Duration: 1m0.004756071s
|
||||
Total Events: 388544
|
||||
Events/sec: 6475.22
|
||||
Success Rate: 100.0%
|
||||
Concurrent Workers: 24
|
||||
Memory Used: 132 MB
|
||||
Avg Latency: 1.723827ms
|
||||
P90 Latency: 5.21331ms
|
||||
P95 Latency: 6.917596ms
|
||||
P99 Latency: 10.942489ms
|
||||
Bottom 10% Avg Latency: 7.705115ms
|
||||
----------------------------------------
|
||||
|
||||
Test: Concurrent Query/Store
|
||||
Duration: 1m0.003409818s
|
||||
Total Events: 309051
|
||||
Events/sec: 5150.56
|
||||
Success Rate: 100.0%
|
||||
Concurrent Workers: 24
|
||||
Memory Used: 99 MB
|
||||
Avg Latency: 1.532079ms
|
||||
P90 Latency: 3.088572ms
|
||||
P95 Latency: 4.004134ms
|
||||
P99 Latency: 6.701092ms
|
||||
Bottom 10% Avg Latency: 4.65921ms
|
||||
----------------------------------------
|
||||
|
||||
Report saved to: /tmp/benchmark_rely-sqlite_8/benchmark_report.txt
|
||||
AsciiDoc report saved to: /tmp/benchmark_rely-sqlite_8/benchmark_report.adoc
|
||||
|
||||
RELAY_NAME: rely-sqlite
|
||||
RELAY_URL: ws://rely-sqlite:3334
|
||||
TEST_TIMESTAMP: 2025-11-22T19:10:18+00:00
|
||||
BENCHMARK_CONFIG:
|
||||
Events: 50000
|
||||
Workers: 24
|
||||
Duration: 60s
|
||||
198
cmd/benchmark/reports/run_20251122_190700/strfry_results.txt
Normal file
198
cmd/benchmark/reports/run_20251122_190700/strfry_results.txt
Normal file
@@ -0,0 +1,198 @@
|
||||
Starting Nostr Relay Benchmark (Badger Backend)
|
||||
Data Directory: /tmp/benchmark_strfry_8
|
||||
Events: 50000, Workers: 24, Duration: 1m0s
|
||||
1763839841101245ℹ️ migrating to version 1... /build/pkg/database/migrations.go:66
|
||||
1763839841101335ℹ️ migrating to version 2... /build/pkg/database/migrations.go:73
|
||||
1763839841101370ℹ️ migrating to version 3... /build/pkg/database/migrations.go:80
|
||||
1763839841101377ℹ️ cleaning up ephemeral events (kinds 20000-29999)... /build/pkg/database/migrations.go:294
|
||||
1763839841101390ℹ️ cleaned up 0 ephemeral events from database /build/pkg/database/migrations.go:339
|
||||
1763839841101408ℹ️ migrating to version 4... /build/pkg/database/migrations.go:87
|
||||
1763839841101414ℹ️ converting events to optimized inline storage (Reiser4 optimization)... /build/pkg/database/migrations.go:347
|
||||
1763839841101428ℹ️ found 0 events to convert (0 regular, 0 replaceable, 0 addressable) /build/pkg/database/migrations.go:436
|
||||
1763839841101435ℹ️ migration complete: converted 0 events to optimized inline storage, deleted 0 old keys /build/pkg/database/migrations.go:545
|
||||
1763839841101455ℹ️ migrating to version 5... /build/pkg/database/migrations.go:94
|
||||
1763839841101462ℹ️ re-encoding events with optimized tag binary format... /build/pkg/database/migrations.go:552
|
||||
1763839841101469ℹ️ found 0 events with e/p tags to re-encode /build/pkg/database/migrations.go:639
|
||||
1763839841101476ℹ️ no events need re-encoding /build/pkg/database/migrations.go:642
|
||||
|
||||
╔════════════════════════════════════════════════════════╗
|
||||
║ BADGER BACKEND BENCHMARK SUITE ║
|
||||
╚════════════════════════════════════════════════════════╝
|
||||
|
||||
=== Starting Badger benchmark ===
|
||||
RunPeakThroughputTest (Badger)..
|
||||
|
||||
=== Peak Throughput Test ===
|
||||
2025/11/22 19:30:41 WARN: Failed to load embedded library from /tmp/orly-libsecp256k1/libsecp256k1.so: Error relocating /tmp/orly-libsecp256k1/libsecp256k1.so: __fprintf_chk: symbol not found, falling back to system paths
|
||||
2025/11/22 19:30:41 INFO: Successfully loaded libsecp256k1 v5.0.0 from system path: libsecp256k1.so.2
|
||||
Events saved: 50000/50000 (100.0%), errors: 0
|
||||
Duration: 3.071426372s
|
||||
Events/sec: 16279.08
|
||||
Avg latency: 1.369757ms
|
||||
P90 latency: 1.839299ms
|
||||
P95 latency: 2.13361ms
|
||||
P99 latency: 3.209938ms
|
||||
Bottom 10% Avg latency: 764.155µs
|
||||
Wiping database between tests...
|
||||
RunBurstPatternTest (Badger)..
|
||||
|
||||
=== Burst Pattern Test ===
|
||||
Burst completed: 5000 events in 283.479669ms
|
||||
Burst completed: 5000 events in 320.332742ms
|
||||
Burst completed: 5000 events in 282.814191ms
|
||||
Burst completed: 5000 events in 305.151074ms
|
||||
Burst completed: 5000 events in 311.552363ms
|
||||
Burst completed: 5000 events in 381.183959ms
|
||||
Burst completed: 5000 events in 312.80669ms
|
||||
Burst completed: 5000 events in 294.748789ms
|
||||
Burst completed: 5000 events in 372.553415ms
|
||||
Burst completed: 5000 events in 328.457439ms
|
||||
Burst test completed: 50000 events in 8.199670789s, errors: 0
|
||||
Events/sec: 6097.81
|
||||
Wiping database between tests...
|
||||
RunMixedReadWriteTest (Badger)..
|
||||
|
||||
=== Mixed Read/Write Test ===
|
||||
Generating 1000 unique synthetic events (minimum 300 bytes each)...
|
||||
Generated 1000 events:
|
||||
Average content size: 312 bytes
|
||||
All events are unique (incremental timestamps)
|
||||
All events are properly signed
|
||||
|
||||
Pre-populating database for read tests...
|
||||
Generating 50000 unique synthetic events (minimum 300 bytes each)...
|
||||
Generated 50000 events:
|
||||
Average content size: 314 bytes
|
||||
All events are unique (incremental timestamps)
|
||||
All events are properly signed
|
||||
|
||||
Mixed test completed: 25000 writes, 25000 reads in 24.666176533s
|
||||
Combined ops/sec: 2027.07
|
||||
Wiping database between tests...
|
||||
RunQueryTest (Badger)..
|
||||
|
||||
=== Query Test ===
|
||||
Generating 10000 unique synthetic events (minimum 300 bytes each)...
|
||||
Generated 10000 events:
|
||||
Average content size: 313 bytes
|
||||
All events are unique (incremental timestamps)
|
||||
All events are properly signed
|
||||
|
||||
Pre-populating database with 10000 events for query tests...
|
||||
Query test completed: 379410 queries in 1m0.006248896s
|
||||
Queries/sec: 6322.84
|
||||
Avg query latency: 1.765248ms
|
||||
P95 query latency: 7.171725ms
|
||||
P99 query latency: 11.436059ms
|
||||
Wiping database between tests...
|
||||
RunConcurrentQueryStoreTest (Badger)..
|
||||
|
||||
=== Concurrent Query/Store Test ===
|
||||
Generating 5000 unique synthetic events (minimum 300 bytes each)...
|
||||
Generated 5000 events:
|
||||
Average content size: 313 bytes
|
||||
All events are unique (incremental timestamps)
|
||||
All events are properly signed
|
||||
|
||||
Pre-populating database with 5000 events for concurrent query/store test...
|
||||
Generating 50000 unique synthetic events (minimum 300 bytes each)...
|
||||
Generated 50000 events:
|
||||
Average content size: 314 bytes
|
||||
All events are unique (incremental timestamps)
|
||||
All events are properly signed
|
||||
|
||||
Concurrent test completed: 305571 operations (255571 queries, 50000 writes) in 1m0.003361786s
|
||||
Operations/sec: 5092.56
|
||||
Avg latency: 1.593158ms
|
||||
Avg query latency: 1.518193ms
|
||||
Avg write latency: 1.976334ms
|
||||
P95 latency: 4.090954ms
|
||||
P99 latency: 7.169741ms
|
||||
|
||||
=== Badger benchmark completed ===
|
||||
|
||||
|
||||
================================================================================
|
||||
BENCHMARK REPORT
|
||||
================================================================================
|
||||
|
||||
Test: Peak Throughput
|
||||
Duration: 3.071426372s
|
||||
Total Events: 50000
|
||||
Events/sec: 16279.08
|
||||
Success Rate: 100.0%
|
||||
Concurrent Workers: 24
|
||||
Memory Used: 102 MB
|
||||
Avg Latency: 1.369757ms
|
||||
P90 Latency: 1.839299ms
|
||||
P95 Latency: 2.13361ms
|
||||
P99 Latency: 3.209938ms
|
||||
Bottom 10% Avg Latency: 764.155µs
|
||||
----------------------------------------
|
||||
|
||||
Test: Burst Pattern
|
||||
Duration: 8.199670789s
|
||||
Total Events: 50000
|
||||
Events/sec: 6097.81
|
||||
Success Rate: 100.0%
|
||||
Concurrent Workers: 24
|
||||
Memory Used: 251 MB
|
||||
Avg Latency: 1.369895ms
|
||||
P90 Latency: 2.004985ms
|
||||
P95 Latency: 2.341095ms
|
||||
P99 Latency: 3.30014ms
|
||||
Bottom 10% Avg Latency: 550.762µs
|
||||
----------------------------------------
|
||||
|
||||
Test: Mixed Read/Write
|
||||
Duration: 24.666176533s
|
||||
Total Events: 50000
|
||||
Events/sec: 2027.07
|
||||
Success Rate: 100.0%
|
||||
Concurrent Workers: 24
|
||||
Memory Used: 205 MB
|
||||
Avg Latency: 381.997µs
|
||||
P90 Latency: 798.95µs
|
||||
P95 Latency: 894.733µs
|
||||
P99 Latency: 1.134289ms
|
||||
Bottom 10% Avg Latency: 1.013526ms
|
||||
----------------------------------------
|
||||
|
||||
Test: Query Performance
|
||||
Duration: 1m0.006248896s
|
||||
Total Events: 379410
|
||||
Events/sec: 6322.84
|
||||
Success Rate: 100.0%
|
||||
Concurrent Workers: 24
|
||||
Memory Used: 128 MB
|
||||
Avg Latency: 1.765248ms
|
||||
P90 Latency: 5.373945ms
|
||||
P95 Latency: 7.171725ms
|
||||
P99 Latency: 11.436059ms
|
||||
Bottom 10% Avg Latency: 8.036698ms
|
||||
----------------------------------------
|
||||
|
||||
Test: Concurrent Query/Store
|
||||
Duration: 1m0.003361786s
|
||||
Total Events: 305571
|
||||
Events/sec: 5092.56
|
||||
Success Rate: 100.0%
|
||||
Concurrent Workers: 24
|
||||
Memory Used: 102 MB
|
||||
Avg Latency: 1.593158ms
|
||||
P90 Latency: 3.181242ms
|
||||
P95 Latency: 4.090954ms
|
||||
P99 Latency: 7.169741ms
|
||||
Bottom 10% Avg Latency: 4.862492ms
|
||||
----------------------------------------
|
||||
|
||||
Report saved to: /tmp/benchmark_strfry_8/benchmark_report.txt
|
||||
AsciiDoc report saved to: /tmp/benchmark_strfry_8/benchmark_report.adoc
|
||||
|
||||
RELAY_NAME: strfry
|
||||
RELAY_URL: ws://strfry:8080
|
||||
TEST_TIMESTAMP: 2025-11-22T19:33:59+00:00
|
||||
BENCHMARK_CONFIG:
|
||||
Events: 50000
|
||||
Workers: 24
|
||||
Duration: 60s
|
||||
@@ -16,7 +16,7 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
currentVersion uint32 = 4
|
||||
currentVersion uint32 = 5
|
||||
)
|
||||
|
||||
func (d *D) RunMigrations() {
|
||||
@@ -90,6 +90,13 @@ func (d *D) RunMigrations() {
|
||||
// bump to version 4
|
||||
_ = d.writeVersionTag(4)
|
||||
}
|
||||
if dbVersion < 5 {
|
||||
log.I.F("migrating to version 5...")
|
||||
// re-encode events with optimized tag binary format (e/p tags)
|
||||
d.ReencodeEventsWithOptimizedTags()
|
||||
// bump to version 5
|
||||
_ = d.writeVersionTag(5)
|
||||
}
|
||||
}
|
||||
|
||||
// writeVersionTag writes a new version tag key to the database (no value)
|
||||
@@ -537,3 +544,140 @@ func (d *D) ConvertSmallEventsToInline() {
|
||||
|
||||
log.I.F("migration complete: converted %d events to optimized inline storage, deleted %d old keys", convertedCount, deletedCount)
|
||||
}
|
||||
|
||||
// ReencodeEventsWithOptimizedTags re-encodes all events to use the new binary
|
||||
// tag format that stores e/p tag values as 33-byte binary (32-byte hash + null)
|
||||
// instead of 64-byte hex strings. This reduces memory usage by ~48% for these tags.
|
||||
func (d *D) ReencodeEventsWithOptimizedTags() {
|
||||
log.I.F("re-encoding events with optimized tag binary format...")
|
||||
var err error
|
||||
|
||||
type EventUpdate struct {
|
||||
Key []byte
|
||||
OldData []byte
|
||||
NewData []byte
|
||||
}
|
||||
|
||||
var updates []EventUpdate
|
||||
var processedCount int
|
||||
|
||||
// Helper to collect event updates from iterator
|
||||
// Only processes regular events (evt prefix) - inline storage already benefits
|
||||
collectUpdates := func(it *badger.Iterator, prefix []byte) error {
|
||||
for it.Rewind(); it.Valid(); it.Next() {
|
||||
item := it.Item()
|
||||
key := item.KeyCopy(nil)
|
||||
|
||||
var val []byte
|
||||
if val, err = item.ValueCopy(nil); chk.E(err) {
|
||||
continue
|
||||
}
|
||||
|
||||
// Regular event storage - data is in value
|
||||
eventData := val
|
||||
if len(eventData) == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
// Decode the event
|
||||
ev := new(event.E)
|
||||
if err = ev.UnmarshalBinary(bytes.NewBuffer(eventData)); chk.E(err) {
|
||||
continue
|
||||
}
|
||||
|
||||
// Check if this event has e or p tags that could benefit from optimization
|
||||
hasOptimizableTags := false
|
||||
if ev.Tags != nil && ev.Tags.Len() > 0 {
|
||||
for _, t := range *ev.Tags {
|
||||
if t.Len() >= 2 {
|
||||
key := t.Key()
|
||||
if len(key) == 1 && (key[0] == 'e' || key[0] == 'p') {
|
||||
hasOptimizableTags = true
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !hasOptimizableTags {
|
||||
continue
|
||||
}
|
||||
|
||||
// Re-encode the event (this will apply the new tag optimization)
|
||||
newData := ev.MarshalBinaryToBytes(nil)
|
||||
|
||||
// Only update if the data actually changed
|
||||
if !bytes.Equal(eventData, newData) {
|
||||
updates = append(updates, EventUpdate{
|
||||
Key: key,
|
||||
OldData: eventData,
|
||||
NewData: newData,
|
||||
})
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Only process regular "evt" prefix events (not inline storage)
|
||||
// Inline storage (sev, rev, aev) already benefits from the optimization
|
||||
// because the binary data is stored directly in the key
|
||||
prf := new(bytes.Buffer)
|
||||
if err = indexes.EventEnc(nil).MarshalWrite(prf); chk.E(err) {
|
||||
return
|
||||
}
|
||||
evtPrefix := prf.Bytes()
|
||||
|
||||
// Collect updates from regular events only
|
||||
if err = d.View(func(txn *badger.Txn) error {
|
||||
it := txn.NewIterator(badger.IteratorOptions{Prefix: evtPrefix})
|
||||
defer it.Close()
|
||||
return collectUpdates(it, evtPrefix)
|
||||
}); chk.E(err) {
|
||||
return
|
||||
}
|
||||
|
||||
log.I.F("found %d events with e/p tags to re-encode", len(updates))
|
||||
|
||||
if len(updates) == 0 {
|
||||
log.I.F("no events need re-encoding")
|
||||
return
|
||||
}
|
||||
|
||||
// Apply updates in batches
|
||||
const batchSize = 1000
|
||||
for i := 0; i < len(updates); i += batchSize {
|
||||
end := i + batchSize
|
||||
if end > len(updates) {
|
||||
end = len(updates)
|
||||
}
|
||||
batch := updates[i:end]
|
||||
|
||||
if err = d.Update(func(txn *badger.Txn) error {
|
||||
for _, upd := range batch {
|
||||
// Since we're only processing regular events (evt prefix),
|
||||
// we just update the value directly
|
||||
if err = txn.Set(upd.Key, upd.NewData); chk.E(err) {
|
||||
log.W.F("failed to update event: %v", err)
|
||||
continue
|
||||
}
|
||||
processedCount++
|
||||
}
|
||||
return nil
|
||||
}); chk.E(err) {
|
||||
log.W.F("batch update failed: %v", err)
|
||||
continue
|
||||
}
|
||||
|
||||
if (i/batchSize)%10 == 0 && i > 0 {
|
||||
log.I.F("progress: %d/%d events re-encoded", i, len(updates))
|
||||
}
|
||||
}
|
||||
|
||||
savedBytes := 0
|
||||
for _, upd := range updates {
|
||||
savedBytes += len(upd.OldData) - len(upd.NewData)
|
||||
}
|
||||
|
||||
log.I.F("migration complete: re-encoded %d events, saved approximately %d bytes (%.2f KB)",
|
||||
processedCount, savedBytes, float64(savedBytes)/1024.0)
|
||||
}
|
||||
|
||||
@@ -291,3 +291,43 @@ func BenchmarkTagsToSliceOfSliceOfStrings(b *testing.B) {
|
||||
})
|
||||
}
|
||||
|
||||
func BenchmarkTagEquals(b *testing.B) {
|
||||
b.Run("BinaryToBinary", func(b *testing.B) {
|
||||
b.ReportAllocs()
|
||||
// Create two tags with same binary-encoded value
|
||||
tag1 := New()
|
||||
_, _ = tag1.Unmarshal([]byte(`["e","0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"]`))
|
||||
tag2 := New()
|
||||
_, _ = tag2.Unmarshal([]byte(`["e","0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"]`))
|
||||
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
_ = tag1.Equals(tag2)
|
||||
}
|
||||
})
|
||||
b.Run("BinaryToHex", func(b *testing.B) {
|
||||
b.ReportAllocs()
|
||||
// One binary-encoded, one hex (simulate comparison with non-optimized tag)
|
||||
tag1 := New()
|
||||
_, _ = tag1.Unmarshal([]byte(`["e","0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"]`))
|
||||
// Create hex version manually (simulating older format)
|
||||
tag2 := NewFromBytesSlice([]byte("e"), []byte("0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"))
|
||||
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
_ = tag1.Equals(tag2)
|
||||
}
|
||||
})
|
||||
b.Run("HexToHex", func(b *testing.B) {
|
||||
b.ReportAllocs()
|
||||
// Both hex (non-optimized tags)
|
||||
tag1 := NewFromBytesSlice([]byte("t"), []byte("0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"))
|
||||
tag2 := NewFromBytesSlice([]byte("t"), []byte("0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"))
|
||||
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
_ = tag1.Equals(tag2)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
"bytes"
|
||||
|
||||
"lol.mleku.dev/errorf"
|
||||
"next.orly.dev/pkg/encoders/hex"
|
||||
"next.orly.dev/pkg/encoders/text"
|
||||
"next.orly.dev/pkg/utils"
|
||||
)
|
||||
@@ -18,6 +19,22 @@ const (
|
||||
Relay
|
||||
)
|
||||
|
||||
// Binary encoding constants for optimized storage of hex-encoded identifiers
|
||||
const (
|
||||
// BinaryEncodedLen is the length of a binary-encoded 32-byte hash with null terminator
|
||||
BinaryEncodedLen = 33
|
||||
// HexEncodedLen is the length of a hex-encoded 32-byte hash
|
||||
HexEncodedLen = 64
|
||||
// HashLen is the raw length of a hash (pubkey/event ID)
|
||||
HashLen = 32
|
||||
)
|
||||
|
||||
// Tags that use binary encoding optimization for their value field
|
||||
var binaryOptimizedTags = map[string]bool{
|
||||
"e": true, // event references
|
||||
"p": true, // pubkey references
|
||||
}
|
||||
|
||||
type T struct {
|
||||
T [][]byte
|
||||
}
|
||||
@@ -76,6 +93,7 @@ func (t *T) Contains(s []byte) (b bool) {
|
||||
}
|
||||
|
||||
// Marshal encodes a tag.T as standard minified JSON array of strings.
|
||||
// Binary-encoded values (e/p tags) are automatically converted back to hex.
|
||||
func (t *T) Marshal(dst []byte) (b []byte) {
|
||||
b = dst
|
||||
// Pre-allocate buffer if nil to reduce reallocations
|
||||
@@ -83,14 +101,25 @@ func (t *T) Marshal(dst []byte) (b []byte) {
|
||||
// Each field might be escaped, so estimate len(field) * 1.5 + 2 quotes + comma
|
||||
if b == nil && len(t.T) > 0 {
|
||||
estimatedSize := 2 // brackets
|
||||
for _, s := range t.T {
|
||||
estimatedSize += len(s)*3/2 + 4 // escaped field + quotes + comma
|
||||
for i, s := range t.T {
|
||||
fieldLen := len(s)
|
||||
// Binary-encoded fields become hex (33 -> 64 chars)
|
||||
if i == Value && isBinaryEncoded(s) {
|
||||
fieldLen = HexEncodedLen
|
||||
}
|
||||
estimatedSize += fieldLen*3/2 + 4 // escaped field + quotes + comma
|
||||
}
|
||||
b = make([]byte, 0, estimatedSize)
|
||||
}
|
||||
b = append(b, '[')
|
||||
for i, s := range t.T {
|
||||
b = text.AppendQuote(b, s, text.NostrEscape)
|
||||
// Convert binary-encoded value fields back to hex for JSON
|
||||
if i == Value && isBinaryEncoded(s) {
|
||||
hexVal := hex.EncAppend(nil, s[:HashLen])
|
||||
b = text.AppendQuote(b, hexVal, text.NostrEscape)
|
||||
} else {
|
||||
b = text.AppendQuote(b, s, text.NostrEscape)
|
||||
}
|
||||
if i < len(t.T)-1 {
|
||||
b = append(b, ',')
|
||||
}
|
||||
@@ -112,6 +141,8 @@ func (t *T) MarshalJSON() (b []byte, err error) {
|
||||
}
|
||||
|
||||
// Unmarshal decodes a standard minified JSON array of strings to a tags.T.
|
||||
// For "e" and "p" tags with 64-character hex values, it converts them to
|
||||
// 33-byte binary format (32 bytes hash + null terminator) for efficiency.
|
||||
func (t *T) Unmarshal(b []byte) (r []byte, err error) {
|
||||
var inQuotes, openedBracket bool
|
||||
var quoteStart int
|
||||
@@ -135,7 +166,23 @@ func (t *T) Unmarshal(b []byte) (r []byte, err error) {
|
||||
// original JSON buffer in-place (which would corrupt subsequent parsing).
|
||||
copyBuf := make([]byte, i-quoteStart)
|
||||
copy(copyBuf, b[quoteStart:i])
|
||||
t.T = append(t.T, text.NostrUnescape(copyBuf))
|
||||
unescaped := text.NostrUnescape(copyBuf)
|
||||
|
||||
// Optimize e/p tag values by converting hex to binary
|
||||
fieldIdx := len(t.T)
|
||||
if fieldIdx == Value && len(t.T) > 0 && shouldOptimize(t.T[Key], unescaped) {
|
||||
// Decode hex to binary format: 32 bytes + null terminator
|
||||
binVal := make([]byte, BinaryEncodedLen)
|
||||
if _, err = hex.DecBytes(binVal[:HashLen], unescaped); err == nil {
|
||||
binVal[HashLen] = 0 // null terminator
|
||||
t.T = append(t.T, binVal)
|
||||
} else {
|
||||
// If decode fails, store as-is
|
||||
t.T = append(t.T, unescaped)
|
||||
}
|
||||
} else {
|
||||
t.T = append(t.T, unescaped)
|
||||
}
|
||||
}
|
||||
}
|
||||
if !openedBracket || inQuotes {
|
||||
@@ -193,3 +240,148 @@ func (t *T) ToSliceOfStrings() (s []string) {
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// isBinaryEncoded checks if a value field is stored in optimized binary format
|
||||
// (32-byte hash + null terminator = 33 bytes total)
|
||||
func isBinaryEncoded(val []byte) bool {
|
||||
return len(val) == BinaryEncodedLen && val[HashLen] == 0
|
||||
}
|
||||
|
||||
// shouldOptimize checks if a tag should use binary encoding optimization
|
||||
func shouldOptimize(key []byte, val []byte) bool {
|
||||
if len(key) != 1 {
|
||||
return false
|
||||
}
|
||||
keyStr := string(key)
|
||||
if !binaryOptimizedTags[keyStr] {
|
||||
return false
|
||||
}
|
||||
// Only optimize if it's a valid 64-character hex string
|
||||
return len(val) == HexEncodedLen && isValidHex(val)
|
||||
}
|
||||
|
||||
// isValidHex checks if all bytes are valid hex characters
|
||||
func isValidHex(b []byte) bool {
|
||||
for _, c := range b {
|
||||
if !((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F')) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// ValueHex returns the value field as hex string. If the value is stored in
|
||||
// binary format, it converts it to hex. Otherwise, it returns the value as-is.
|
||||
func (t *T) ValueHex() []byte {
|
||||
if t == nil || len(t.T) <= Value {
|
||||
return nil
|
||||
}
|
||||
val := t.T[Value]
|
||||
if isBinaryEncoded(val) {
|
||||
// Convert binary back to hex
|
||||
return hex.EncAppend(nil, val[:HashLen])
|
||||
}
|
||||
return val
|
||||
}
|
||||
|
||||
// ValueBinary returns the raw binary value if it's binary-encoded, or nil otherwise.
|
||||
// This is useful for database operations that need the raw hash bytes.
|
||||
func (t *T) ValueBinary() []byte {
|
||||
if t == nil || len(t.T) <= Value {
|
||||
return nil
|
||||
}
|
||||
val := t.T[Value]
|
||||
if isBinaryEncoded(val) {
|
||||
return val[:HashLen]
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Equals compares two tags for equality, handling both binary and hex encodings.
|
||||
// This ensures that ["e", "abc..."] and ["e", <binary>] are equal if they
|
||||
// represent the same hash. This method does NOT allocate memory.
|
||||
func (t *T) Equals(other *T) bool {
|
||||
if t == nil && other == nil {
|
||||
return true
|
||||
}
|
||||
if t == nil || other == nil {
|
||||
return false
|
||||
}
|
||||
if len(t.T) != len(other.T) {
|
||||
return false
|
||||
}
|
||||
for i := range t.T {
|
||||
if i == Value && len(t.T) > Value {
|
||||
// Special handling for value field to compare binary vs hex without allocating
|
||||
tVal := t.T[Value]
|
||||
oVal := other.T[Value]
|
||||
|
||||
tIsBinary := isBinaryEncoded(tVal)
|
||||
oIsBinary := isBinaryEncoded(oVal)
|
||||
|
||||
// Both binary - compare first 32 bytes directly
|
||||
if tIsBinary && oIsBinary {
|
||||
if !bytes.Equal(tVal[:HashLen], oVal[:HashLen]) {
|
||||
return false
|
||||
}
|
||||
} else if tIsBinary || oIsBinary {
|
||||
// One is binary, one is hex - need to compare carefully
|
||||
// Compare the binary one's raw bytes with hex-decoded version of the other
|
||||
var binBytes, hexBytes []byte
|
||||
if tIsBinary {
|
||||
binBytes = tVal[:HashLen]
|
||||
hexBytes = oVal
|
||||
} else {
|
||||
binBytes = oVal[:HashLen]
|
||||
hexBytes = tVal
|
||||
}
|
||||
|
||||
// Decode hex inline without allocation by comparing byte by byte
|
||||
if len(hexBytes) != HexEncodedLen {
|
||||
return false
|
||||
}
|
||||
for j := 0; j < HashLen; j++ {
|
||||
// Convert two hex chars to one byte and compare
|
||||
hi := hexBytes[j*2]
|
||||
lo := hexBytes[j*2+1]
|
||||
|
||||
var hiByte, loByte byte
|
||||
if hi >= '0' && hi <= '9' {
|
||||
hiByte = hi - '0'
|
||||
} else if hi >= 'a' && hi <= 'f' {
|
||||
hiByte = hi - 'a' + 10
|
||||
} else if hi >= 'A' && hi <= 'F' {
|
||||
hiByte = hi - 'A' + 10
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
|
||||
if lo >= '0' && lo <= '9' {
|
||||
loByte = lo - '0'
|
||||
} else if lo >= 'a' && lo <= 'f' {
|
||||
loByte = lo - 'a' + 10
|
||||
} else if lo >= 'A' && lo <= 'F' {
|
||||
loByte = lo - 'A' + 10
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
|
||||
expectedByte := (hiByte << 4) | loByte
|
||||
if binBytes[j] != expectedByte {
|
||||
return false
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Both are regular (hex or other) - direct comparison
|
||||
if !bytes.Equal(tVal, oVal) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if !bytes.Equal(t.T[i], other.T[i]) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -30,3 +30,207 @@ func TestMarshalUnmarshal(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TestBinaryEncodingOptimization verifies that e/p tags are stored in binary format
|
||||
func TestBinaryEncodingOptimization(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
json string
|
||||
expectBinary bool
|
||||
internalLen int // expected length of Value() field in internal storage
|
||||
}{
|
||||
{
|
||||
name: "e tag with hex value",
|
||||
json: `["e","0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"]`,
|
||||
expectBinary: true,
|
||||
internalLen: BinaryEncodedLen, // 33 bytes (32 + null terminator)
|
||||
},
|
||||
{
|
||||
name: "p tag with hex value",
|
||||
json: `["p","fedcba9876543210fedcba9876543210fedcba9876543210fedcba9876543210"]`,
|
||||
expectBinary: true,
|
||||
internalLen: BinaryEncodedLen,
|
||||
},
|
||||
{
|
||||
name: "e tag with relay",
|
||||
json: `["e","0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef","wss://relay.example.com"]`,
|
||||
expectBinary: true,
|
||||
internalLen: BinaryEncodedLen,
|
||||
},
|
||||
{
|
||||
name: "t tag not optimized",
|
||||
json: `["t","bitcoin"]`,
|
||||
expectBinary: false,
|
||||
internalLen: 7, // "bitcoin" as-is
|
||||
},
|
||||
{
|
||||
name: "e tag with short value not optimized",
|
||||
json: `["e","short"]`,
|
||||
expectBinary: false,
|
||||
internalLen: 5,
|
||||
},
|
||||
{
|
||||
name: "e tag with invalid hex not optimized",
|
||||
json: `["e","zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz"]`,
|
||||
expectBinary: false,
|
||||
internalLen: 64,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
tag := New()
|
||||
_, err := tag.Unmarshal([]byte(tc.json))
|
||||
if err != nil {
|
||||
t.Fatalf("Unmarshal failed: %v", err)
|
||||
}
|
||||
|
||||
// Check internal storage length
|
||||
if tag.Len() < 2 {
|
||||
t.Fatal("Tag should have at least 2 fields")
|
||||
}
|
||||
|
||||
valueField := tag.T[Value]
|
||||
if len(valueField) != tc.internalLen {
|
||||
t.Errorf("Expected internal value length %d, got %d", tc.internalLen, len(valueField))
|
||||
}
|
||||
|
||||
// Check if binary encoded as expected
|
||||
if tc.expectBinary {
|
||||
if !isBinaryEncoded(valueField) {
|
||||
t.Error("Expected binary encoding, but tag is not binary encoded")
|
||||
}
|
||||
// Verify null terminator
|
||||
if valueField[HashLen] != 0 {
|
||||
t.Error("Binary encoded value should have null terminator at position 32")
|
||||
}
|
||||
} else {
|
||||
if isBinaryEncoded(valueField) {
|
||||
t.Error("Did not expect binary encoding, but tag is binary encoded")
|
||||
}
|
||||
}
|
||||
|
||||
// Marshal back to JSON and verify it matches original
|
||||
marshaled := tag.Marshal(nil)
|
||||
if string(marshaled) != tc.json {
|
||||
t.Errorf("Marshaled JSON doesn't match original.\nExpected: %s\nGot: %s", tc.json, string(marshaled))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// TestValueHexMethod verifies ValueHex() correctly converts binary to hex
|
||||
func TestValueHexMethod(t *testing.T) {
|
||||
json := `["e","0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"]`
|
||||
tag := New()
|
||||
_, err := tag.Unmarshal([]byte(json))
|
||||
if err != nil {
|
||||
t.Fatalf("Unmarshal failed: %v", err)
|
||||
}
|
||||
|
||||
// Internal storage should be binary
|
||||
if !isBinaryEncoded(tag.T[Value]) {
|
||||
t.Fatal("Expected binary encoding")
|
||||
}
|
||||
|
||||
// ValueHex should return the original hex string
|
||||
hexVal := tag.ValueHex()
|
||||
expectedHex := "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
|
||||
if string(hexVal) != expectedHex {
|
||||
t.Errorf("ValueHex returned wrong value.\nExpected: %s\nGot: %s", expectedHex, string(hexVal))
|
||||
}
|
||||
}
|
||||
|
||||
// TestValueBinaryMethod verifies ValueBinary() returns raw hash bytes
|
||||
func TestValueBinaryMethod(t *testing.T) {
|
||||
json := `["p","0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"]`
|
||||
tag := New()
|
||||
_, err := tag.Unmarshal([]byte(json))
|
||||
if err != nil {
|
||||
t.Fatalf("Unmarshal failed: %v", err)
|
||||
}
|
||||
|
||||
// ValueBinary should return 32 bytes
|
||||
binVal := tag.ValueBinary()
|
||||
if binVal == nil {
|
||||
t.Fatal("ValueBinary returned nil")
|
||||
}
|
||||
if len(binVal) != HashLen {
|
||||
t.Errorf("Expected %d bytes, got %d", HashLen, len(binVal))
|
||||
}
|
||||
|
||||
// It should match the first 32 bytes of the internal storage
|
||||
if !utils.FastEqual(binVal, tag.T[Value][:HashLen]) {
|
||||
t.Error("ValueBinary doesn't match internal storage")
|
||||
}
|
||||
}
|
||||
|
||||
// TestEqualsMethod verifies Equals() handles binary vs hex comparison
|
||||
func TestEqualsMethod(t *testing.T) {
|
||||
// Create tag from JSON (will be binary internally)
|
||||
tag1 := New()
|
||||
_, err := tag1.Unmarshal([]byte(`["e","0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"]`))
|
||||
if err != nil {
|
||||
t.Fatalf("Unmarshal failed: %v", err)
|
||||
}
|
||||
|
||||
// Create identical tag
|
||||
tag2 := New()
|
||||
_, err = tag2.Unmarshal([]byte(`["e","0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"]`))
|
||||
if err != nil {
|
||||
t.Fatalf("Unmarshal failed: %v", err)
|
||||
}
|
||||
|
||||
if !tag1.Equals(tag2) {
|
||||
t.Error("Identical tags should be equal")
|
||||
}
|
||||
|
||||
// Create tag with different value
|
||||
tag3 := New()
|
||||
_, err = tag3.Unmarshal([]byte(`["e","fedcba9876543210fedcba9876543210fedcba9876543210fedcba9876543210"]`))
|
||||
if err != nil {
|
||||
t.Fatalf("Unmarshal failed: %v", err)
|
||||
}
|
||||
|
||||
if tag1.Equals(tag3) {
|
||||
t.Error("Different tags should not be equal")
|
||||
}
|
||||
|
||||
// Test with relay field
|
||||
tag4 := New()
|
||||
_, err = tag4.Unmarshal([]byte(`["e","0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef","wss://relay.example.com"]`))
|
||||
if err != nil {
|
||||
t.Fatalf("Unmarshal failed: %v", err)
|
||||
}
|
||||
|
||||
if tag1.Equals(tag4) {
|
||||
t.Error("Tags with different lengths should not be equal")
|
||||
}
|
||||
}
|
||||
|
||||
// TestBinaryEncodingSavesSpace verifies the optimization reduces memory usage
|
||||
func TestBinaryEncodingSavesSpace(t *testing.T) {
|
||||
// Tag without optimization (non-hex or non e/p tag)
|
||||
tagNonOpt := New()
|
||||
_, _ = tagNonOpt.Unmarshal([]byte(`["t","0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"]`))
|
||||
nonOptSize := len(tagNonOpt.T[Value])
|
||||
|
||||
// Tag with optimization
|
||||
tagOpt := New()
|
||||
_, _ = tagOpt.Unmarshal([]byte(`["e","0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"]`))
|
||||
optSize := len(tagOpt.T[Value])
|
||||
|
||||
// Binary should be smaller (33 vs 64 bytes)
|
||||
if optSize >= nonOptSize {
|
||||
t.Errorf("Binary encoding should save space. Non-opt: %d bytes, Opt: %d bytes", nonOptSize, optSize)
|
||||
}
|
||||
|
||||
expectedSavings := HexEncodedLen - BinaryEncodedLen // 64 - 33 = 31 bytes
|
||||
actualSavings := nonOptSize - optSize
|
||||
if actualSavings != expectedSavings {
|
||||
t.Errorf("Expected to save %d bytes, actually saved %d bytes", expectedSavings, actualSavings)
|
||||
}
|
||||
|
||||
t.Logf("Space savings: %d bytes per e/p tag value (%.1f%% reduction)",
|
||||
actualSavings, float64(actualSavings)/float64(nonOptSize)*100)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user