You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
358 lines
8.3 KiB
358 lines
8.3 KiB
package text |
|
|
|
import ( |
|
"testing" |
|
|
|
"lukechampine.com/frand" |
|
"next.orly.dev/pkg/crypto/sha256" |
|
"next.orly.dev/pkg/encoders/hex" |
|
) |
|
|
|
func createTestData() []byte { |
|
return []byte(`some text content with line breaks and tabs and other stuff, and also some < > & " ' / \ control chars \u0000 \u001f`) |
|
} |
|
|
|
func createTestDataLarge() []byte { |
|
data := make([]byte, 8192) |
|
for i := range data { |
|
data[i] = byte(i % 256) |
|
} |
|
return data |
|
} |
|
|
|
func createTestHexArray() [][]byte { |
|
ha := make([][]byte, 20) |
|
h := make([]byte, sha256.Size) |
|
frand.Read(h) |
|
for i := range ha { |
|
hh := sha256.Sum256(h) |
|
h = hh[:] |
|
ha[i] = make([]byte, sha256.Size) |
|
copy(ha[i], h) |
|
} |
|
return ha |
|
} |
|
|
|
func BenchmarkNostrEscape(b *testing.B) { |
|
b.Run("Small", func(b *testing.B) { |
|
b.ReportAllocs() |
|
src := createTestData() |
|
dst := make([]byte, 0, len(src)*2) |
|
for i := 0; i < b.N; i++ { |
|
dst = NostrEscape(dst[:0], src) |
|
} |
|
}) |
|
b.Run("Large", func(b *testing.B) { |
|
b.ReportAllocs() |
|
src := createTestDataLarge() |
|
dst := make([]byte, 0, len(src)*2) |
|
for i := 0; i < b.N; i++ { |
|
dst = NostrEscape(dst[:0], src) |
|
} |
|
}) |
|
b.Run("NoEscapes", func(b *testing.B) { |
|
b.ReportAllocs() |
|
src := []byte("this is a normal string with no special characters") |
|
dst := make([]byte, 0, len(src)) |
|
for i := 0; i < b.N; i++ { |
|
dst = NostrEscape(dst[:0], src) |
|
} |
|
}) |
|
b.Run("ManyEscapes", func(b *testing.B) { |
|
b.ReportAllocs() |
|
src := []byte("\"test\"\n\t\r\b\f\\control\x00\x01\x02") |
|
dst := make([]byte, 0, len(src)*3) |
|
for i := 0; i < b.N; i++ { |
|
dst = NostrEscape(dst[:0], src) |
|
} |
|
}) |
|
} |
|
|
|
func BenchmarkNostrUnescape(b *testing.B) { |
|
b.Run("Small", func(b *testing.B) { |
|
b.ReportAllocs() |
|
src := createTestData() |
|
escaped := NostrEscape(nil, src) |
|
for i := 0; i < b.N; i++ { |
|
escapedCopy := make([]byte, len(escaped)) |
|
copy(escapedCopy, escaped) |
|
_ = NostrUnescape(escapedCopy) |
|
} |
|
}) |
|
b.Run("Large", func(b *testing.B) { |
|
b.ReportAllocs() |
|
src := createTestDataLarge() |
|
escaped := NostrEscape(nil, src) |
|
for i := 0; i < b.N; i++ { |
|
escapedCopy := make([]byte, len(escaped)) |
|
copy(escapedCopy, escaped) |
|
_ = NostrUnescape(escapedCopy) |
|
} |
|
}) |
|
} |
|
|
|
func BenchmarkRoundTripEscape(b *testing.B) { |
|
b.Run("Small", func(b *testing.B) { |
|
b.ReportAllocs() |
|
src := createTestData() |
|
for i := 0; i < b.N; i++ { |
|
escaped := NostrEscape(nil, src) |
|
escapedCopy := make([]byte, len(escaped)) |
|
copy(escapedCopy, escaped) |
|
_ = NostrUnescape(escapedCopy) |
|
} |
|
}) |
|
b.Run("Large", func(b *testing.B) { |
|
b.ReportAllocs() |
|
src := createTestDataLarge() |
|
for i := 0; i < b.N; i++ { |
|
escaped := NostrEscape(nil, src) |
|
escapedCopy := make([]byte, len(escaped)) |
|
copy(escapedCopy, escaped) |
|
_ = NostrUnescape(escapedCopy) |
|
} |
|
}) |
|
} |
|
|
|
func BenchmarkJSONKey(b *testing.B) { |
|
b.ReportAllocs() |
|
key := []byte("testkey") |
|
dst := make([]byte, 0, 20) |
|
for i := 0; i < b.N; i++ { |
|
dst = JSONKey(dst[:0], key) |
|
} |
|
} |
|
|
|
func BenchmarkUnmarshalHex(b *testing.B) { |
|
b.Run("Small", func(b *testing.B) { |
|
b.ReportAllocs() |
|
h := make([]byte, sha256.Size) |
|
frand.Read(h) |
|
hexStr := hex.EncAppend(nil, h) |
|
quoted := AppendQuote(nil, hexStr, Noop) |
|
for i := 0; i < b.N; i++ { |
|
_, _, _ = UnmarshalHex(quoted) |
|
} |
|
}) |
|
b.Run("Large", func(b *testing.B) { |
|
b.ReportAllocs() |
|
h := make([]byte, 1024) |
|
frand.Read(h) |
|
hexStr := hex.EncAppend(nil, h) |
|
quoted := AppendQuote(nil, hexStr, Noop) |
|
for i := 0; i < b.N; i++ { |
|
_, _, _ = UnmarshalHex(quoted) |
|
} |
|
}) |
|
} |
|
|
|
func BenchmarkUnmarshalQuoted(b *testing.B) { |
|
b.Run("Small", func(b *testing.B) { |
|
b.ReportAllocs() |
|
src := createTestData() |
|
quoted := AppendQuote(nil, src, NostrEscape) |
|
for i := 0; i < b.N; i++ { |
|
quotedCopy := make([]byte, len(quoted)) |
|
copy(quotedCopy, quoted) |
|
_, _, _ = UnmarshalQuoted(quotedCopy) |
|
} |
|
}) |
|
b.Run("Large", func(b *testing.B) { |
|
b.ReportAllocs() |
|
src := createTestDataLarge() |
|
quoted := AppendQuote(nil, src, NostrEscape) |
|
for i := 0; i < b.N; i++ { |
|
quotedCopy := make([]byte, len(quoted)) |
|
copy(quotedCopy, quoted) |
|
_, _, _ = UnmarshalQuoted(quotedCopy) |
|
} |
|
}) |
|
} |
|
|
|
func BenchmarkMarshalHexArray(b *testing.B) { |
|
b.Run("Small", func(b *testing.B) { |
|
b.ReportAllocs() |
|
ha := createTestHexArray() |
|
dst := make([]byte, 0, len(ha)*sha256.Size*3) |
|
for i := 0; i < b.N; i++ { |
|
dst = MarshalHexArray(dst[:0], ha) |
|
} |
|
}) |
|
b.Run("Large", func(b *testing.B) { |
|
b.ReportAllocs() |
|
ha := make([][]byte, 100) |
|
h := make([]byte, sha256.Size) |
|
frand.Read(h) |
|
for i := range ha { |
|
hh := sha256.Sum256(h) |
|
h = hh[:] |
|
ha[i] = make([]byte, sha256.Size) |
|
copy(ha[i], h) |
|
} |
|
dst := make([]byte, 0, len(ha)*sha256.Size*3) |
|
for i := 0; i < b.N; i++ { |
|
dst = MarshalHexArray(dst[:0], ha) |
|
} |
|
}) |
|
} |
|
|
|
func BenchmarkUnmarshalHexArray(b *testing.B) { |
|
b.Run("Small", func(b *testing.B) { |
|
b.ReportAllocs() |
|
ha := createTestHexArray() |
|
marshaled := MarshalHexArray(nil, ha) |
|
for i := 0; i < b.N; i++ { |
|
marshaledCopy := make([]byte, len(marshaled)) |
|
copy(marshaledCopy, marshaled) |
|
_, _, _ = UnmarshalHexArray(marshaledCopy, sha256.Size) |
|
} |
|
}) |
|
b.Run("Large", func(b *testing.B) { |
|
b.ReportAllocs() |
|
ha := make([][]byte, 100) |
|
h := make([]byte, sha256.Size) |
|
frand.Read(h) |
|
for i := range ha { |
|
hh := sha256.Sum256(h) |
|
h = hh[:] |
|
ha[i] = make([]byte, sha256.Size) |
|
copy(ha[i], h) |
|
} |
|
marshaled := MarshalHexArray(nil, ha) |
|
for i := 0; i < b.N; i++ { |
|
marshaledCopy := make([]byte, len(marshaled)) |
|
copy(marshaledCopy, marshaled) |
|
_, _, _ = UnmarshalHexArray(marshaledCopy, sha256.Size) |
|
} |
|
}) |
|
} |
|
|
|
func BenchmarkUnmarshalStringArray(b *testing.B) { |
|
b.Run("Small", func(b *testing.B) { |
|
b.ReportAllocs() |
|
strings := [][]byte{ |
|
[]byte("string1"), |
|
[]byte("string2"), |
|
[]byte("string3"), |
|
} |
|
dst := make([]byte, 0, 100) |
|
dst = append(dst, '[') |
|
for i, s := range strings { |
|
dst = AppendQuote(dst, s, NostrEscape) |
|
if i < len(strings)-1 { |
|
dst = append(dst, ',') |
|
} |
|
} |
|
dst = append(dst, ']') |
|
for i := 0; i < b.N; i++ { |
|
dstCopy := make([]byte, len(dst)) |
|
copy(dstCopy, dst) |
|
_, _, _ = UnmarshalStringArray(dstCopy) |
|
} |
|
}) |
|
b.Run("Large", func(b *testing.B) { |
|
b.ReportAllocs() |
|
strings := make([][]byte, 100) |
|
for i := range strings { |
|
strings[i] = []byte("test string " + string(rune(i))) |
|
} |
|
dst := make([]byte, 0, 2000) |
|
dst = append(dst, '[') |
|
for i, s := range strings { |
|
dst = AppendQuote(dst, s, NostrEscape) |
|
if i < len(strings)-1 { |
|
dst = append(dst, ',') |
|
} |
|
} |
|
dst = append(dst, ']') |
|
for i := 0; i < b.N; i++ { |
|
dstCopy := make([]byte, len(dst)) |
|
copy(dstCopy, dst) |
|
_, _, _ = UnmarshalStringArray(dstCopy) |
|
} |
|
}) |
|
} |
|
|
|
func BenchmarkAppendQuote(b *testing.B) { |
|
b.Run("Small", func(b *testing.B) { |
|
b.ReportAllocs() |
|
src := createTestData() |
|
dst := make([]byte, 0, len(src)*2) |
|
for i := 0; i < b.N; i++ { |
|
dst = AppendQuote(dst[:0], src, NostrEscape) |
|
} |
|
}) |
|
b.Run("Large", func(b *testing.B) { |
|
b.ReportAllocs() |
|
src := createTestDataLarge() |
|
dst := make([]byte, 0, len(src)*2) |
|
for i := 0; i < b.N; i++ { |
|
dst = AppendQuote(dst[:0], src, NostrEscape) |
|
} |
|
}) |
|
b.Run("NoEscape", func(b *testing.B) { |
|
b.ReportAllocs() |
|
src := []byte("normal string") |
|
dst := make([]byte, 0, len(src)+2) |
|
for i := 0; i < b.N; i++ { |
|
dst = AppendQuote(dst[:0], src, Noop) |
|
} |
|
}) |
|
} |
|
|
|
func BenchmarkAppendList(b *testing.B) { |
|
b.Run("Small", func(b *testing.B) { |
|
b.ReportAllocs() |
|
src := [][]byte{ |
|
[]byte("item1"), |
|
[]byte("item2"), |
|
[]byte("item3"), |
|
} |
|
dst := make([]byte, 0, 50) |
|
for i := 0; i < b.N; i++ { |
|
dst = AppendList(dst[:0], src, ',', NostrEscape) |
|
} |
|
}) |
|
b.Run("Large", func(b *testing.B) { |
|
b.ReportAllocs() |
|
src := make([][]byte, 100) |
|
for i := range src { |
|
src[i] = []byte("item" + string(rune(i))) |
|
} |
|
dst := make([]byte, 0, 2000) |
|
for i := 0; i < b.N; i++ { |
|
dst = AppendList(dst[:0], src, ',', NostrEscape) |
|
} |
|
}) |
|
} |
|
|
|
func BenchmarkMarshalBool(b *testing.B) { |
|
b.ReportAllocs() |
|
dst := make([]byte, 0, 10) |
|
for i := 0; i < b.N; i++ { |
|
dst = MarshalBool(dst[:0], i%2 == 0) |
|
} |
|
} |
|
|
|
func BenchmarkUnmarshalBool(b *testing.B) { |
|
b.Run("True", func(b *testing.B) { |
|
b.ReportAllocs() |
|
src := []byte("true") |
|
for i := 0; i < b.N; i++ { |
|
srcCopy := make([]byte, len(src)) |
|
copy(srcCopy, src) |
|
_, _, _ = UnmarshalBool(srcCopy) |
|
} |
|
}) |
|
b.Run("False", func(b *testing.B) { |
|
b.ReportAllocs() |
|
src := []byte("false") |
|
for i := 0; i < b.N; i++ { |
|
srcCopy := make([]byte, len(src)) |
|
copy(srcCopy, src) |
|
_, _, _ = UnmarshalBool(srcCopy) |
|
} |
|
}) |
|
} |
|
|
|
|
|
|