diff --git a/go.mod b/go.mod index e423e24..b5a9781 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/nbd-wtf/go-nostr -go 1.18 +go 1.20 require ( github.com/btcsuite/btcd/btcec/v2 v2.2.0 diff --git a/nson/nson.go b/nson/nson.go index 87be2cc..03e9fa5 100644 --- a/nson/nson.go +++ b/nson/nson.go @@ -6,6 +6,7 @@ import ( "fmt" "strconv" "strings" + "unsafe" "github.com/nbd-wtf/go-nostr" ) @@ -44,6 +45,10 @@ const ( var NotNSON = fmt.Errorf("not nson") +func UnmarshalBytes(data []byte, evt *nostr.Event) (err error) { + return Unmarshal(unsafe.String(unsafe.SliceData(data), len(data)), evt) +} + // Unmarshal turns a NSON string into a nostr.Event struct func Unmarshal(data string, evt *nostr.Event) (err error) { defer func() { @@ -105,6 +110,11 @@ func Unmarshal(data string, evt *nostr.Event) (err error) { return err } +func MarshalBytes(evt *nostr.Event) ([]byte, error) { + v, err := Marshal(evt) + return unsafe.Slice(unsafe.StringData(v), len(v)), err +} + func Marshal(evt *nostr.Event) (string, error) { // start building the nson descriptors (without the first byte that represents the nson size) nsonBuf := make([]byte, 256) diff --git a/nson/nson_test.go b/nson/nson_test.go index 1b1d5ea..24cfc45 100644 --- a/nson/nson_test.go +++ b/nson/nson_test.go @@ -169,15 +169,25 @@ func BenchmarkNSONEncoding(b *testing.B) { } } }) + + b.Run("nson.Marshal to bytes", func(b *testing.B) { + for i := 0; i < b.N; i++ { + for _, evt := range events { + MarshalBytes(evt) + } + } + }) } func BenchmarkNSONDecoding(b *testing.B) { events := make([]string, len(normalEvents)) + eventsB := make([][]byte, len(normalEvents)) for i, jevt := range normalEvents { evt := &nostr.Event{} json.Unmarshal([]byte(jevt), evt) nevt, _ := Marshal(evt) events[i] = nevt + eventsB[i] = []byte(nevt) } b.Run("json.Unmarshal", func(b *testing.B) { @@ -204,6 +214,18 @@ func BenchmarkNSONDecoding(b *testing.B) { } }) + b.Run("nson.Unmarshal from bytes", func(b *testing.B) { + for i := 0; i < b.N; i++ { + for _, nevt := range eventsB { + evt := &nostr.Event{} + err := UnmarshalBytes(nevt, evt) + if err != nil { + b.Fatalf("failed to unmarshal: %s", err) + } + } + } + }) + b.Run("json.Unmarshal + sig verification", func(b *testing.B) { for i := 0; i < b.N; i++ { for _, nevt := range events {