Subject: [PATCH] utils --- Index: internal/caseconv/swar.go IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== diff --git a/internal/caseconv/swar.go b/internal/caseconv/swar.go --- a/internal/caseconv/swar.go (revision 01f52863bec45ba8ea67c7e26605e1f11b43b9a1) +++ b/internal/caseconv/swar.go (date 1783799972755) @@ -10,6 +10,12 @@ // in github.com/gofiber/utils/v2/swar. Byte order inside a word does not // matter for the case folds themselves (every operation is per byte lane), // so these helpers are correct on both little- and big-endian platforms. +// +// Words move through encoding/binary rather than swar.Load8/swar.Store8 on +// purpose: the binary.LittleEndian forms measure ~9% faster in the in-place +// word loops here (benchstat -count=10, Go 1.25, Apple M2 Pro). The lane +// order is identical, so swar words and binary.LittleEndian loads/stores +// can be mixed freely. // WordLen is the SWAR word width in bytes, re-exported for the case // conversion callers in the strings and bytes packages: they route inputs @@ -107,6 +113,9 @@ // byte that lower-casing changes: when len(src) >= WordLen the overlapping // tail store rewrites dst[n-WordLen:from) with case-converted bytes, which is // only a no-op under that precondition. +// +// Callers currently invoke this only with len(src) >= WordLen; the byte-wise +// tail below keeps the helper correct standalone for shorter inputs. func ToLowerCopy(dst, src []byte, from int) { n := len(src) i := from @@ -130,7 +139,8 @@ // len(dst) must equal len(src). // // from must be a multiple of WordLen and at or below the index of the first -// byte that upper-casing changes; see ToLowerCopy for why. +// byte that upper-casing changes; see ToLowerCopy for why, including the +// note on the byte-wise tail. func ToUpperCopy(dst, src []byte, from int) { n := len(src) i := from Index: swar/swar_test.go IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== diff --git a/swar/swar_test.go b/swar/swar_test.go --- a/swar/swar_test.go (revision 01f52863bec45ba8ea67c7e26605e1f11b43b9a1) +++ b/swar/swar_test.go (date 1783799410860) @@ -2,6 +2,7 @@ import ( "encoding/binary" + "math/rand" "testing" "github.com/stretchr/testify/require" @@ -22,6 +23,29 @@ require.Equal(t, uint64(0x0A09080706050403), Load8(string(b), 2)) } +func Test_Store8_LaneOrder_RoundTrip(t *testing.T) { + t.Parallel() + b := make([]byte, 12) + Store8(b, 2, 0x0807060504030201) + require.Equal(t, []byte{0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 0, 0}, b) + // Load8/Store8 round trip at every offset, leaving neighbors untouched. + src := []byte{0xFF, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xAA, 0xBB} + for i := 0; i+8 <= len(src); i++ { + dst := make([]byte, len(src)) + copy(dst, src) + Store8(dst, i, Load8(src, i)) + require.Equal(t, src, dst, "offset %d", i) + } +} + +func Test_Broadcast(t *testing.T) { + t.Parallel() + for _, c := range []byte{0x00, 0x01, '0', 'a', 0x7F, 0x80, 0xFF} { + want := wordFromLanes([8]byte{c, c, c, c, c, c, c, c}) + require.Equal(t, want, Broadcast(c), "byte 0x%02x", c) + } +} + func Test_ToLowerWord_ToUpperWord_Exhaustive(t *testing.T) { t.Parallel() // Every byte value in every lane position, once with all other lanes @@ -88,32 +112,50 @@ func Test_MatchRangeMask_Exhaustive(t *testing.T) { t.Parallel() - ranges := [][2]byte{ - {'0', '9'}, - {'a', 'z'}, - {'A', 'Z'}, - {0x00, 0x1F}, - {0x09, 0x0D}, - {0x00, 0x7F}, - {0x20, 0x20}, - {0x7F, 0x7F}, - {0x00, 0x00}, - } - for _, r := range ranges { - lo, hi := r[0], r[1] - for c := range 256 { - for lane := range 8 { - var lanes [8]byte - for i := range lanes { - lanes[i] = 0xFF // never in range: high bit set - } - lanes[lane] = byte(c) - m := MatchRangeMask(wordFromLanes(lanes), lo, hi) - want := uint64(0) - if byte(c) >= lo && byte(c) <= hi && c < 0x80 { - want = 0x80 << (8 * lane) - } - require.Equal(t, want, m, "range [0x%02x,0x%02x] byte 0x%02x lane %d", lo, hi, c, lane) + // All valid (lo, hi) pairs, with every byte value rotating through the + // lanes. The neighbor lanes hold the range boundaries and both extremes + // rather than a constant fill: the carry-freedom claim is exactly about + // adjacent-lane interaction. Plain checks keep the ~2M words fast. + for lo := 0; lo <= 0x7F; lo++ { + for hi := lo; hi <= 0x7F; hi++ { + base := [8]byte{0x00, byte(lo), byte(hi), byte(lo) - 1, byte(hi) + 1, 0x7F, 0x80, 0xFF} + for c := range 256 { + lanes := base + lanes[c&7] = byte(c) + m := MatchRangeMask(wordFromLanes(lanes), byte(lo), byte(hi)) + for i, v := range lanes { + want := uint64(0) + if v >= byte(lo) && v <= byte(hi) && v < 0x80 { + want = 0x80 + } + if got := m >> (8 * i) & 0xFF; got != want { + t.Fatalf("range [0x%02x,0x%02x] lanes %v lane %d: got 0x%02x want 0x%02x", + lo, hi, lanes, i, got, want) + } + } + } + } + } + + // Random valid ranges over fully random lanes, as a second angle on + // mixed neighbor values. + rng := rand.New(rand.NewSource(11)) //nolint:gosec // deterministic test data + for range 200000 { + lo := byte(rng.Intn(0x80)) + hi := lo + byte(rng.Intn(0x80-int(lo))) + var lanes [8]byte + for i := range lanes { + lanes[i] = byte(rng.Intn(256)) + } + m := MatchRangeMask(wordFromLanes(lanes), lo, hi) + for i, v := range lanes { + want := uint64(0) + if v >= lo && v <= hi && v < 0x80 { + want = 0x80 + } + if got := m >> (8 * i) & 0xFF; got != want { + t.Fatalf("range [0x%02x,0x%02x] lanes %v lane %d: got 0x%02x want 0x%02x", + lo, hi, lanes, i, got, want) } } } @@ -136,7 +178,9 @@ // generic instantiation shows a ~4-8x slower word loop. If this benchmark // ever collapses to per-byte speed, the reslice idiom in Load8 has stopped // fusing and Load8 needs concrete string/[]byte helpers behind the generic -// front. +// front. The guard is advisory only, it cannot fail CI; eyeball it (or +// benchstat it against the previous toolchain) when touching Load8/Store8 +// or bumping the Go version. The store leg covers Store8's write fusion. func Benchmark_Load8_Fusion(b *testing.B) { buf := make([]byte, 4096) for i := range buf { @@ -163,6 +207,15 @@ } _ = acc }) + b.Run("store", func(b *testing.B) { + b.SetBytes(int64(len(buf))) + w := Broadcast('x') + for b.Loop() { + for i := 0; i+8 <= len(buf); i += 8 { + Store8(buf, i, w) + } + } + }) } func Test_ZeroLanes_FirstMatchProperty(t *testing.T) { Index: swar/swar.go IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== diff --git a/swar/swar.go b/swar/swar.go --- a/swar/swar.go (revision 01f52863bec45ba8ea67c7e26605e1f11b43b9a1) +++ b/swar/swar.go (date 1783799320863) @@ -6,10 +6,15 @@ // e.g. finding a delimiter while simultaneously classifying the bytes before // it — without re-deriving the bit tricks. // -// Every operation is carried out independently per byte lane, so results are -// identical on little- and big-endian platforms. Load8 always assembles words -// in little-endian lane order: lane 0 (the least significant byte) is the -// lowest byte index, which is what FirstLane and LastLane assume. +// Every operation yields per-lane results (exactly for the Match* masks, +// approximately for ZeroLanes, whose contract allows false positives above +// the first hit), so results are identical on little- and big-endian +// platforms. Load8 and Store8 always use little-endian lane order: lane 0 +// (the least significant byte) is the lowest byte index, which is what +// FirstLane and LastLane assume. The empty-mask sentinels differ on +// purpose: FirstLane(0) == 8 lets forward scans step past the current word +// arithmetically, while LastLane(0) == -1 is the conventional not-found +// result for reverse scans. // // No unsafe is used anywhere in this package. package swar @@ -51,6 +56,31 @@ uint64(w[7])<<56 } +// Store8 writes w into b[i:i+8] in Load8's lane order: lane 0 (the least +// significant byte) lands at the lowest byte index, so a Load8/Store8 round +// trip is the identity. The caller must guarantee i+8 <= len(b); the +// reslice below turns a violation into a bounds panic. Like Load8, the +// constant-index writes are bounds-check free and fuse into a single 8-byte +// store on little-endian targets. +func Store8(b []byte, i int, w uint64) { + d := b[i : i+8] + d[0] = byte(w) + d[1] = byte(w >> 8) + d[2] = byte(w >> 16) + d[3] = byte(w >> 24) + d[4] = byte(w >> 32) + d[5] = byte(w >> 40) + d[6] = byte(w >> 48) + d[7] = byte(w >> 56) +} + +// Broadcast returns a word with c in every byte lane, the needle form that +// ZeroLanes scans consume. Hoist the result out of word loops; it compiles +// to a single multiply. +func Broadcast(c byte) uint64 { + return uint64(c) * Ones +} + // ToLowerWord lower-cases every 'A'..'Z' lane in w. All other bytes, // including those >= 0x80, pass through unchanged — bit-identical to the // ASCII case-conversion tables used elsewhere in this module. @@ -68,9 +98,9 @@ // lane of x; higher lanes may carry false positives (borrows propagate // strictly upward from true zero lanes), and the mask is zero iff x has no // zero byte. It is two ops cheaper than MatchByteMask, which makes it the -// right primitive for first-match scans — typically as -// ZeroLanes(w ^ needleBroadcast) with the uint64(c)*Ones broadcast hoisted -// out of the word loop. Use MatchByteMask when every lane must be exact. +// right primitive for first-match scans, typically as +// ZeroLanes(w ^ Broadcast(c)) with the broadcast hoisted out of the word +// loop. Use MatchByteMask when every lane must be exact. func ZeroLanes(x uint64) uint64 { return (x - Ones) &^ x & HighBits } Index: swar_verify_test.go IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== diff --git a/swar_verify_test.go b/swar_verify_test.go --- a/swar_verify_test.go (revision 01f52863bec45ba8ea67c7e26605e1f11b43b9a1) +++ b/swar_verify_test.go (date 1783799603943) @@ -18,7 +18,9 @@ rng := rand.New(rand.NewSource(42)) //nolint:gosec // deterministic test data for range 20000 { - n := rng.Intn(70) + // Lengths 0..100 cover sub-word inputs, all %8 tails, and several + // full word iterations. + n := rng.Intn(101) a := make([]byte, n) b := make([]byte, n) for i := range n { @@ -116,3 +118,45 @@ func asciiFoldUpperB(b []byte) []byte { return []byte(asciiFoldUpper(string(b))) } + +// Test_CaseCopy_FromOffsets pins the from > 0 contract of ToLowerCopy and +// ToUpperCopy directly: from is word-aligned and at or below the first byte +// the conversion changes, so the overlapping tail store may rewrite +// dst[n-8:from) only as a no-op. The public wrappers exercise this path +// indirectly; this test does it without them. +func Test_CaseCopy_FromOffsets(t *testing.T) { + t.Parallel() + for n := 8; n <= 26; n++ { + for from := 0; from < n; from += 8 { + // Case-stable filler (digits): bytes before firstChange must not + // change under either conversion, or from would be invalid. + base := make([]byte, n) + for i := range base { + base[i] = byte('0' + i%10) + } + for firstChange := from; firstChange < n; firstChange++ { + lsrc := append([]byte(nil), base...) + lsrc[firstChange] = 'A' + byte(firstChange%26) + if firstChange+1 < n { + lsrc[firstChange+1] = 0xE9 // non-ASCII passthrough + } + dst := make([]byte, n) + copy(dst[:from], lsrc[:from]) + caseconv.ToLowerCopy(dst, lsrc, from) + require.Equal(t, asciiFoldLower(string(lsrc)), string(dst), + "lower n=%d from=%d change=%d", n, from, firstChange) + + usrc := append([]byte(nil), base...) + usrc[firstChange] = 'a' + byte(firstChange%26) + if firstChange+1 < n { + usrc[firstChange+1] = 0xE9 + } + dst2 := make([]byte, n) + copy(dst2[:from], usrc[:from]) + caseconv.ToUpperCopy(dst2, usrc, from) + require.Equal(t, asciiFoldUpper(string(usrc)), string(dst2), + "upper n=%d from=%d change=%d", n, from, firstChange) + } + } + } +} Index: fuzz_test.go IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== diff --git a/fuzz_test.go b/fuzz_test.go new file mode 100644 --- /dev/null (date 1783799619336) +++ b/fuzz_test.go (date 1783799619336) @@ -0,0 +1,104 @@ +package utils + +import ( + "bytes" + "strconv" + "testing" +) + +// Fuzz targets comparing the SWAR implementations against the scalar +// references from the unit tests. The seeds cover the known traps (HTAB, +// CR|0x20, overlap tails, 19-20 digit boundaries); go test runs the seeds +// as regular tests, go test -fuzz explores beyond them. + +func FuzzIndexFold(f *testing.F) { + f.Add("max-age=0,No-Cache,private", "no-cache") + f.Add("no\rcache", "no-cache") + f.Add("aaaaaaaaaaaaNO-CACHE", "no-cache") + f.Add("aaaaaaagz", "gzip") + f.Add("__Proxy-Authorization: basic", "proxy-authorization") + f.Add("\xe9abc", "\xc9abc") + f.Add("", "") + f.Fuzz(func(t *testing.T, s, needle string) { + want := refIndexFold(s, needle) + if got := IndexFold(s, needle); got != want { + t.Fatalf("IndexFold(%q, %q) = %d, want %d", s, needle, got, want) + } + if got := IndexFold([]byte(s), needle); got != want { + t.Fatalf("IndexFold(bytes %q, %q) = %d, want %d", s, needle, got, want) + } + if got := ContainsFold(s, needle); got != (want >= 0) { + t.Fatalf("ContainsFold(%q, %q) = %v, want %v", s, needle, got, want >= 0) + } + }) +} + +func FuzzEqualFold(f *testing.F) { + f.Add("Content-Type", "content-type") + f.Add("no\rcache", "no-cache") + f.Add("\xc9abc", "\xe9abc") + f.Add("aaaaaaaaaaaaX", "aaaaaaaaaaaax") + f.Fuzz(func(t *testing.T, a, b string) { + want := bytes.Equal(asciiFoldUpperB([]byte(a)), asciiFoldUpperB([]byte(b))) + if got := EqualFold(a, b); got != want { + t.Fatalf("EqualFold(%q, %q) = %v, want %v", a, b, got, want) + } + if got := EqualFold([]byte(a), []byte(b)); got != want { + t.Fatalf("EqualFold(bytes %q, %q) = %v, want %v", a, b, got, want) + } + }) +} + +func FuzzParse(f *testing.F) { + f.Add("9223372036854775807") + f.Add("9223372036854775808") + f.Add("18446744073709551616") + f.Add("00000000000000000001") + f.Add("-9223372036854775808") + f.Add("12345678\n2345678") + f.Add("+0") + f.Fuzz(func(t *testing.T, s string) { + gotU, errU := ParseUint(s) + wantU, wantErrU := strconv.ParseUint(s, 10, 64) + if (errU == nil) != (wantErrU == nil) { + t.Fatalf("ParseUint(%q) err = %v, strconv err = %v", s, errU, wantErrU) + } + switch { + case wantErrU == nil && gotU != wantU: + t.Fatalf("ParseUint(%q) = %d, want %d", s, gotU, wantU) + case wantErrU != nil && gotU != 0: + // Unlike strconv, this library returns 0 (not a clamped value) + // alongside every error. + t.Fatalf("ParseUint(%q) returned %d with error", s, gotU) + } + + gotI, errI := ParseInt(s) + wantI, wantErrI := strconv.ParseInt(s, 10, 64) + if (errI == nil) != (wantErrI == nil) { + t.Fatalf("ParseInt(%q) err = %v, strconv err = %v", s, errI, wantErrI) + } + switch { + case wantErrI == nil && gotI != wantI: + t.Fatalf("ParseInt(%q) = %d, want %d", s, gotI, wantI) + case wantErrI != nil && gotI != 0: + t.Fatalf("ParseInt(%q) returned %d with error", s, gotI) + } + }) +} + +func FuzzIndexNonQuotable(f *testing.F) { + f.Add("a\tb") + f.Add("aaaaaaaa\t\x1f") + f.Add("\xff\xff\xff\xff\xff\xff\xff\"") + f.Add("caf\xc3\xa9 r\xc3\xa9sum\xc3\xa9.pdf") + f.Add("name\\quoted") + f.Fuzz(func(t *testing.T, s string) { + want := refIndexNonQuotable(s) + if got := IndexNonQuotable(s); got != want { + t.Fatalf("IndexNonQuotable(%q) = %d, want %d", s, got, want) + } + if got, wantASCII := IsASCII(s), isASCIIRef(s); got != wantASCII { + t.Fatalf("IsASCII(%q) = %v, want %v", s, got, wantASCII) + } + }) +} Index: search_test.go IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== diff --git a/search_test.go b/search_test.go --- a/search_test.go (revision 01f52863bec45ba8ea67c7e26605e1f11b43b9a1) +++ b/search_test.go (date 1783799567455) @@ -82,7 +82,9 @@ rng := rand.New(rand.NewSource(7)) //nolint:gosec // deterministic test data for range 30000 { - n := rng.Intn(41) // lengths 0..40 cover all %8 tails and overlap reads + // Lengths 0..100 cover all %8 tails, the overlap reads, and 2+ + // iterations of IsASCII's 32-byte unrolled loop. + n := rng.Intn(101) buf := make([]byte, n) for i := range buf { // Small alphabet so needles hit often, plus occasional raw bytes. @@ -156,7 +158,7 @@ require.Equal(t, 10, IndexFold("max-age=0,No-Cache,private", "no-cache")) require.Equal(t, 4, IndexFold([]byte("xyz BeArEr token"), "bearer")) // Fold must only touch A-Z/a-z lanes: CR|0x20 == '-' would falsely match - // with a blanket |0x20 fold. This is the trap case from the handoff. + // with a blanket |0x20 fold. require.Equal(t, -1, IndexFold("no\rcache", "no-cache")) require.Equal(t, -1, IndexFold("NO\rCACHE", "no-cache")) // Non-ASCII bytes must match exactly, never fold. Index: AGENTS.md IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 --- /dev/null (date 1783798938961) +++ b/AGENTS.md (date 1783798938961) @@ -0,0 +1,20 @@ +# AGENTS.md + +Guidance for AI coding agents working in this repository. + +## What this repository is + +gofiber/utils is a helper library for [Fiber](https://github.com/gofiber/fiber) and its middleware ecosystem. It exports fast, low-allocation helpers; the consumers live in other modules (fiber itself, middleware, user code). + +## Reviewing and proposing API changes + +- Exported functions without in-module callers are by design. Do not argue that a new public function or package should move to `internal/` because grep finds no non-test usage inside this module. In-module usage counts say nothing about the value of the API; exporting helpers for downstream modules is the purpose of this repository. +- Judge new exported API instead by: contract clarity (documented preconditions, aliasing rules, edge cases), test coverage (including property or fuzz tests for bit-twiddling code), naming consistency with the existing surface, and benchmark evidence for performance claims. +- Additive API is not a SemVer break, but it is a long-term maintenance commitment. Call out sharp-edged contracts (unchecked preconditions, approximate results, unsafe memory semantics) explicitly so maintainers approve them consciously. + +## Conventions + +- Performance claims are verified with benchstat (base vs. head on the same machine, at least `-count=10`), never with single runs. +- `make test` runs the suite with race detector and shuffle; `make lint` runs golangci-lint; `make format` applies gofumpt; `make benchfmt` aligns the benchmark tables in README.md. +- README.md is a function catalog with benchmark blocks. New exported functions need a README section, and benchmark numbers for touched paths should be regenerated in the same run. +- Code, comments, commit messages, and PR text are always written in English. Index: search.go IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== diff --git a/search.go b/search.go --- a/search.go (revision 01f52863bec45ba8ea67c7e26605e1f11b43b9a1) +++ b/search.go (date 1783800975815) @@ -22,8 +22,8 @@ if n >= 8 { // The needle broadcasts are hoisted here so sub-word inputs never // pay for the multiplies. - bcA := uint64(a) * swar.Ones - bcB := uint64(b) * swar.Ones + bcA := swar.Broadcast(a) + bcB := swar.Broadcast(b) i := 0 for ; i+8 <= n; i += 8 { w := swar.Load8(s, i) @@ -53,9 +53,9 @@ func IndexAny3[S byteSeq](s S, a, b, c byte) int { n := len(s) if n >= 8 { - bcA := uint64(a) * swar.Ones - bcB := uint64(b) * swar.Ones - bcC := uint64(c) * swar.Ones + bcA := swar.Broadcast(a) + bcB := swar.Broadcast(b) + bcC := swar.Broadcast(c) i := 0 for ; i+8 <= n; i += 8 { w := swar.Load8(s, i) @@ -84,6 +84,8 @@ // of needle in s, or -1 if absent. An empty needle matches at index 0. Only // 'A'..'Z'/'a'..'z' fold; every other byte (including >= 0x80) must match // exactly, so e.g. "no\rcache" does NOT match the needle "no-cache". +// The needle is a plain string by design: call sites pass constant tokens, +// and a []byte needle would cost its callers a conversion either way. func IndexFold[S byteSeq](s S, needle string) int { n, k := len(s), len(needle) if k == 0 { @@ -103,18 +105,19 @@ // then verify each candidate. Approximate-mask false positives just // cost a verify; the candidate order stays low-to-high, so the // pos > last cutoff remains a valid global exit. - bc1 := uint64(first) * swar.Ones + bc1 := swar.Broadcast(first) bc2 := bc1 if first >= 'a' && first <= 'z' { - bc2 = uint64(first-0x20) * swar.Ones + bc2 = swar.Broadcast(first - 0x20) } // For needles up to one word the verify is a single masked word // compare against the folded needle, built lazily on the first - // candidate; longer needles fold-compare word-at-a-time. The verify - // block is deliberately spelled out in both loops below: routing it - // through a closure taxes every call with capture setup even on the - // no-candidate path, so keep the two copies in sync. + // candidate; longer needles fold-compare word-at-a-time. The lazy + // build is load-bearing: building eagerly costs the no-candidate + // path +44% on 8-byte misses and +13% to +17% on 32-64B misses + // (benchstat -count=10, Go 1.25, Apple M2 Pro). foldPrep keeps the + // pair computation in one place for both build sites below. var needleWord, lenMask uint64 built := false @@ -129,8 +132,7 @@ } if k <= 8 { if !built { - needleWord = foldNeedle(needle) - lenMask = ^uint64(0) >> ((8 - k) * 8) + needleWord, lenMask = foldPrep(needle) built = true } if foldedWindowAt(s, pos, lenMask) == needleWord { @@ -149,8 +151,7 @@ for ; i <= last; i++ { if table[s[i]] == first { if !built { - needleWord = foldNeedle(needle) - lenMask = ^uint64(0) >> ((8 - k) * 8) + needleWord, lenMask = foldPrep(needle) built = true } if foldedWindowAt(s, i, lenMask) == needleWord { @@ -177,6 +178,13 @@ return -1 } +// foldPrep returns the folded needle word and its length mask for the +// short-needle (k <= 8) verify. It exists so IndexFold's two lazy build +// sites share one definition of the pair. +func foldPrep(needle string) (uint64, uint64) { + return foldNeedle(needle), ^uint64(0) >> ((8 - len(needle)) * 8) +} + // foldNeedle returns needle lower-cased into one little-endian word, lane 0 // holding needle[0]. len(needle) must be 1..8; lanes past the needle are // zero, matching the ^uint64(0) >> ((8-k)*8) mask callers apply to windows. Index: parse_swar_test.go IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== diff --git a/parse_swar_test.go b/parse_swar_test.go --- a/parse_swar_test.go (revision 01f52863bec45ba8ea67c7e26605e1f11b43b9a1) +++ b/parse_swar_test.go (date 1783799584860) @@ -2,14 +2,14 @@ // Tests and benchmarks for the 8-digit SWAR parse step in ParseUint/ParseInt. // -// Historical gate notes: the IsIPv4/IsIPv6 SWAR pre-validation (handoff P6) -// was prototyped here and DROPPED — it lost on every shape (+10% to +49%) -// because the scalar octet parse still has to run after the word checks on -// <= 15-byte inputs. The scalar-baseline comparison that gated P7 lives in -// the introducing commit's message; ParseUint won -16% to -27% at 8+ digits -// with a one-branch cost on 1-digit inputs. +// A SWAR pre-validation for IsIPv4/IsIPv6 was prototyped alongside this work +// and dropped: it lost on every shape (+10% to +49%) because the scalar +// octet parse still has to run after the word checks on <= 15-byte inputs. +// ParseUint won -16% to -27% at 8+ digits with a one-branch cost on 1-digit +// inputs; the raw comparison lives in the introducing commit message. import ( + "math" "math/rand" "strconv" "testing" @@ -40,6 +40,20 @@ lanes[lane] = '1' } } + + // Pin parse8Digits itself on random 8-digit words, independent of the + // full-parser parity loop. + rng := rand.New(rand.NewSource(5)) //nolint:gosec // deterministic test data + for range 10000 { + v := uint64(rng.Intn(100000000)) + s := FormatUint(v) + for len(s) < 8 { + s = "0" + s + } + w := swar.Load8(s, 0) + require.True(t, isEightDigits(w), s) + require.Equal(t, v, parse8Digits(w), s) + } } func Test_ParseSWAR_Parity(t *testing.T) { @@ -122,6 +136,16 @@ require.Equal(t, int32(-214748364), v32) _, err = ParseInt32("-21474836480") require.Error(t, err) + + // 19-digit boundary on the sign-free fast path: MaxInt64 parses, one + // past it is a range error (not a syntax error), matching strconv. + maxV, err := ParseInt("9223372036854775807") + require.NoError(t, err) + require.Equal(t, int64(math.MaxInt64), maxV) + _, err = ParseInt("9223372036854775808") + var numErr *strconv.NumError + require.ErrorAs(t, err, &numErr) + require.ErrorIs(t, numErr.Err, strconv.ErrRange) } func Benchmark_ParseUint_DigitRuns(b *testing.B) { Index: README.md IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== diff --git a/README.md b/README.md --- a/README.md (revision 01f52863bec45ba8ea67c7e26605e1f11b43b9a1) +++ b/README.md (date 1783800835605) @@ -20,345 +20,425 @@ // go test ./... -benchmem -run=^$ -bench=Benchmark_ -count=1 # Case Conversion -Benchmark_ToLowerBytes/empty/fiber-12 601228760 1.955 ns/op 0 B/op 0 allocs/op -Benchmark_ToLowerBytes/empty/fiber/unsafe-12 601901127 1.977 ns/op 0 B/op 0 allocs/op -Benchmark_ToLowerBytes/empty/default-12 361526772 3.343 ns/op 0 B/op 0 allocs/op -Benchmark_ToLowerBytes/http-get/fiber-12 356280168 3.373 ns/op 0 B/op 0 allocs/op -Benchmark_ToLowerBytes/http-get/fiber/unsafe-12 232881622 5.121 ns/op 0 B/op 0 allocs/op -Benchmark_ToLowerBytes/http-get/default-12 64825149 18.35 ns/op 8 B/op 1 allocs/op -Benchmark_ToLowerBytes/http-get-upper/fiber-12 95134903 12.71 ns/op 3 B/op 1 allocs/op -Benchmark_ToLowerBytes/http-get-upper/fiber/unsafe-12 233711541 5.175 ns/op 0 B/op 0 allocs/op -Benchmark_ToLowerBytes/http-get-upper/default-12 83459391 13.94 ns/op 8 B/op 1 allocs/op -Benchmark_ToLowerBytes/header-content-type-mixed/fiber-12 46423608 25.82 ns/op 48 B/op 1 allocs/op -Benchmark_ToLowerBytes/header-content-type-mixed/fiber/unsafe-12 94087516 12.69 ns/op 0 B/op 0 allocs/op -Benchmark_ToLowerBytes/header-content-type-mixed/default-12 25226778 47.33 ns/op 48 B/op 1 allocs/op -Benchmark_ToLowerBytes/large-lower/fiber-12 42942836 27.95 ns/op 0 B/op 0 allocs/op -Benchmark_ToLowerBytes/large-lower/fiber/unsafe-12 61712125 19.44 ns/op 0 B/op 0 allocs/op -Benchmark_ToLowerBytes/large-lower/default-12 17121913 69.94 ns/op 64 B/op 1 allocs/op -Benchmark_ToLowerBytes/large-upper/fiber-12 36060220 33.69 ns/op 64 B/op 1 allocs/op -Benchmark_ToLowerBytes/large-upper/fiber/unsafe-12 61862710 19.45 ns/op 0 B/op 0 allocs/op -Benchmark_ToLowerBytes/large-upper/default-12 16092603 74.24 ns/op 64 B/op 1 allocs/op -Benchmark_ToLowerBytes/large-mixed/fiber-12 35001792 34.35 ns/op 64 B/op 1 allocs/op -Benchmark_ToLowerBytes/large-mixed/fiber/unsafe-12 62047836 19.42 ns/op 0 B/op 0 allocs/op -Benchmark_ToLowerBytes/large-mixed/default-12 16119986 74.45 ns/op 64 B/op 1 allocs/op -Benchmark_ToUpperBytes/empty/fiber-12 621527377 1.948 ns/op 0 B/op 0 allocs/op -Benchmark_ToUpperBytes/empty/fiber/unsafe-12 620614620 1.903 ns/op 0 B/op 0 allocs/op -Benchmark_ToUpperBytes/empty/default-12 347387406 3.339 ns/op 0 B/op 0 allocs/op -Benchmark_ToUpperBytes/http-get/fiber-12 93976990 12.81 ns/op 3 B/op 1 allocs/op -Benchmark_ToUpperBytes/http-get/fiber/unsafe-12 228022617 5.177 ns/op 0 B/op 0 allocs/op -Benchmark_ToUpperBytes/http-get/default-12 80799015 14.77 ns/op 8 B/op 1 allocs/op -Benchmark_ToUpperBytes/http-get-upper/fiber-12 353756593 3.385 ns/op 0 B/op 0 allocs/op -Benchmark_ToUpperBytes/http-get-upper/fiber/unsafe-12 234419678 5.132 ns/op 0 B/op 0 allocs/op -Benchmark_ToUpperBytes/http-get-upper/default-12 63601288 18.92 ns/op 8 B/op 1 allocs/op -Benchmark_ToUpperBytes/header-content-type-mixed/fiber-12 44992688 26.51 ns/op 48 B/op 1 allocs/op -Benchmark_ToUpperBytes/header-content-type-mixed/fiber/unsafe-12 95225496 12.77 ns/op 0 B/op 0 allocs/op -Benchmark_ToUpperBytes/header-content-type-mixed/default-12 22269578 53.94 ns/op 48 B/op 1 allocs/op -Benchmark_ToUpperBytes/large-lower/fiber-12 35570046 33.42 ns/op 64 B/op 1 allocs/op -Benchmark_ToUpperBytes/large-lower/fiber/unsafe-12 61963066 19.52 ns/op 0 B/op 0 allocs/op -Benchmark_ToUpperBytes/large-lower/default-12 14771874 80.05 ns/op 64 B/op 1 allocs/op -Benchmark_ToUpperBytes/large-upper/fiber-12 43817876 27.94 ns/op 0 B/op 0 allocs/op -Benchmark_ToUpperBytes/large-upper/fiber/unsafe-12 61968400 19.39 ns/op 0 B/op 0 allocs/op -Benchmark_ToUpperBytes/large-upper/default-12 14641957 81.42 ns/op 64 B/op 1 allocs/op -Benchmark_ToUpperBytes/large-mixed/fiber-12 35656184 34.25 ns/op 64 B/op 1 allocs/op -Benchmark_ToUpperBytes/large-mixed/fiber/unsafe-12 56226717 19.48 ns/op 0 B/op 0 allocs/op -Benchmark_ToUpperBytes/large-mixed/default-12 14955886 80.25 ns/op 64 B/op 1 allocs/op -Benchmark_ToUpper/empty/fiber-12 539313216 2.018 ns/op 0 B/op 0 allocs/op -Benchmark_ToUpper/empty/fiber/unsafe-12 634806298 1.889 ns/op 0 B/op 0 allocs/op -Benchmark_ToUpper/empty/default-12 638947015 1.882 ns/op 0 B/op 0 allocs/op -Benchmark_ToUpper/http-get/fiber-12 95414156 12.67 ns/op 3 B/op 1 allocs/op -Benchmark_ToUpper/http-get/fiber/unsafe-12 234368000 5.118 ns/op 0 B/op 0 allocs/op -Benchmark_ToUpper/http-get/default-12 60732201 19.48 ns/op 8 B/op 1 allocs/op -Benchmark_ToUpper/http-get-upper/fiber-12 248156660 4.837 ns/op 0 B/op 0 allocs/op -Benchmark_ToUpper/http-get-upper/fiber/unsafe-12 234148320 5.125 ns/op 0 B/op 0 allocs/op -Benchmark_ToUpper/http-get-upper/default-12 234811851 5.098 ns/op 0 B/op 0 allocs/op -Benchmark_ToUpper/header-content-type-mixed/fiber-12 45805240 26.20 ns/op 48 B/op 1 allocs/op -Benchmark_ToUpper/header-content-type-mixed/fiber/unsafe-12 93765258 12.83 ns/op 0 B/op 0 allocs/op -Benchmark_ToUpper/header-content-type-mixed/default-12 11631184 103.2 ns/op 48 B/op 1 allocs/op -Benchmark_ToUpper/large-lower/fiber-12 36103797 33.35 ns/op 64 B/op 1 allocs/op -Benchmark_ToUpper/large-lower/fiber/unsafe-12 56551980 20.95 ns/op 0 B/op 0 allocs/op -Benchmark_ToUpper/large-lower/default-12 5996400 177.5 ns/op 64 B/op 1 allocs/op -Benchmark_ToUpper/large-upper/fiber-12 28375362 42.48 ns/op 0 B/op 0 allocs/op -Benchmark_ToUpper/large-upper/fiber/unsafe-12 61935218 19.44 ns/op 0 B/op 0 allocs/op -Benchmark_ToUpper/large-upper/default-12 19255944 61.54 ns/op 0 B/op 0 allocs/op -Benchmark_ToUpper/large-mixed/fiber-12 36390100 33.16 ns/op 64 B/op 1 allocs/op -Benchmark_ToUpper/large-mixed/fiber/unsafe-12 62494440 19.35 ns/op 0 B/op 0 allocs/op -Benchmark_ToUpper/large-mixed/default-12 5833207 204.4 ns/op 64 B/op 1 allocs/op -Benchmark_ToLower/empty/fiber-12 613171694 1.947 ns/op 0 B/op 0 allocs/op -Benchmark_ToLower/empty/fiber/unsafe-12 647631400 1.858 ns/op 0 B/op 0 allocs/op -Benchmark_ToLower/empty/default-12 638164638 1.883 ns/op 0 B/op 0 allocs/op -Benchmark_ToLower/http-get/fiber-12 394179825 3.058 ns/op 0 B/op 0 allocs/op -Benchmark_ToLower/http-get/fiber/unsafe-12 235441498 5.085 ns/op 0 B/op 0 allocs/op -Benchmark_ToLower/http-get/default-12 279097488 4.179 ns/op 0 B/op 0 allocs/op -Benchmark_ToLower/http-get-upper/fiber-12 98945953 12.38 ns/op 3 B/op 1 allocs/op -Benchmark_ToLower/http-get-upper/fiber/unsafe-12 236656982 5.051 ns/op 0 B/op 0 allocs/op -Benchmark_ToLower/http-get-upper/default-12 62779154 19.15 ns/op 8 B/op 1 allocs/op -Benchmark_ToLower/header-content-type-mixed/fiber-12 47738392 25.17 ns/op 48 B/op 1 allocs/op -Benchmark_ToLower/header-content-type-mixed/fiber/unsafe-12 94119801 12.68 ns/op 0 B/op 0 allocs/op -Benchmark_ToLower/header-content-type-mixed/default-12 18145400 65.65 ns/op 48 B/op 1 allocs/op -Benchmark_ToLower/large-lower/fiber-12 44083813 27.34 ns/op 0 B/op 0 allocs/op -Benchmark_ToLower/large-lower/fiber/unsafe-12 60995110 19.58 ns/op 0 B/op 0 allocs/op -Benchmark_ToLower/large-lower/default-12 24336615 48.71 ns/op 0 B/op 0 allocs/op -Benchmark_ToLower/large-upper/fiber-12 35895274 33.27 ns/op 64 B/op 1 allocs/op -Benchmark_ToLower/large-upper/fiber/unsafe-12 61949072 19.50 ns/op 0 B/op 0 allocs/op -Benchmark_ToLower/large-upper/default-12 7084752 168.0 ns/op 64 B/op 1 allocs/op -Benchmark_ToLower/large-mixed/fiber-12 35053681 34.56 ns/op 64 B/op 1 allocs/op -Benchmark_ToLower/large-mixed/fiber/unsafe-12 61658090 19.58 ns/op 0 B/op 0 allocs/op -Benchmark_ToLower/large-mixed/default-12 5924719 206.8 ns/op 64 B/op 1 allocs/op +Benchmark_ToLowerBytes/empty/fiber-12 599341221 1.970 ns/op 0 B/op 0 allocs/op +Benchmark_ToLowerBytes/empty/fiber/unsafe-12 613673802 1.951 ns/op 0 B/op 0 allocs/op +Benchmark_ToLowerBytes/empty/default-12 363300402 3.316 ns/op 0 B/op 0 allocs/op +Benchmark_ToLowerBytes/http-get/fiber-12 350302147 3.434 ns/op 0 B/op 0 allocs/op +Benchmark_ToLowerBytes/http-get/fiber/unsafe-12 250488015 4.803 ns/op 0 B/op 0 allocs/op +Benchmark_ToLowerBytes/http-get/default-12 65883986 18.03 ns/op 8 B/op 1 allocs/op +Benchmark_ToLowerBytes/http-get-upper/fiber-12 95234625 12.53 ns/op 3 B/op 1 allocs/op +Benchmark_ToLowerBytes/http-get-upper/fiber/unsafe-12 242418936 4.802 ns/op 0 B/op 0 allocs/op +Benchmark_ToLowerBytes/http-get-upper/default-12 86405012 13.85 ns/op 8 B/op 1 allocs/op +Benchmark_ToLowerBytes/header-content-type-mixed/fiber-12 52263289 22.74 ns/op 48 B/op 1 allocs/op +Benchmark_ToLowerBytes/header-content-type-mixed/fiber/unsafe-12 131711175 9.101 ns/op 0 B/op 0 allocs/op +Benchmark_ToLowerBytes/header-content-type-mixed/default-12 25312339 47.13 ns/op 48 B/op 1 allocs/op +Benchmark_ToLowerBytes/large-lower/fiber-12 120148472 10.02 ns/op 0 B/op 0 allocs/op +Benchmark_ToLowerBytes/large-lower/fiber/unsafe-12 100000000 10.57 ns/op 0 B/op 0 allocs/op +Benchmark_ToLowerBytes/large-lower/default-12 16746064 71.43 ns/op 64 B/op 1 allocs/op +Benchmark_ToLowerBytes/large-upper/fiber-12 46270634 26.82 ns/op 64 B/op 1 allocs/op +Benchmark_ToLowerBytes/large-upper/fiber/unsafe-12 100000000 10.71 ns/op 0 B/op 0 allocs/op +Benchmark_ToLowerBytes/large-upper/default-12 15734505 76.92 ns/op 64 B/op 1 allocs/op +Benchmark_ToLowerBytes/large-mixed/fiber-12 46607823 26.06 ns/op 64 B/op 1 allocs/op +Benchmark_ToLowerBytes/large-mixed/fiber/unsafe-12 100000000 10.86 ns/op 0 B/op 0 allocs/op +Benchmark_ToLowerBytes/large-mixed/default-12 16291084 73.76 ns/op 64 B/op 1 allocs/op +Benchmark_ToUpperBytes/empty/fiber-12 607678140 1.976 ns/op 0 B/op 0 allocs/op +Benchmark_ToUpperBytes/empty/fiber/unsafe-12 611928006 1.981 ns/op 0 B/op 0 allocs/op +Benchmark_ToUpperBytes/empty/default-12 362632894 3.309 ns/op 0 B/op 0 allocs/op +Benchmark_ToUpperBytes/http-get/fiber-12 95358867 12.55 ns/op 3 B/op 1 allocs/op +Benchmark_ToUpperBytes/http-get/fiber/unsafe-12 249490471 4.905 ns/op 0 B/op 0 allocs/op +Benchmark_ToUpperBytes/http-get/default-12 79248020 14.63 ns/op 8 B/op 1 allocs/op +Benchmark_ToUpperBytes/http-get-upper/fiber-12 365516280 3.330 ns/op 0 B/op 0 allocs/op +Benchmark_ToUpperBytes/http-get-upper/fiber/unsafe-12 249981619 4.803 ns/op 0 B/op 0 allocs/op +Benchmark_ToUpperBytes/http-get-upper/default-12 64343162 19.01 ns/op 8 B/op 1 allocs/op +Benchmark_ToUpperBytes/header-content-type-mixed/fiber-12 52506741 22.69 ns/op 48 B/op 1 allocs/op +Benchmark_ToUpperBytes/header-content-type-mixed/fiber/unsafe-12 130478352 9.350 ns/op 0 B/op 0 allocs/op +Benchmark_ToUpperBytes/header-content-type-mixed/default-12 22415607 54.44 ns/op 48 B/op 1 allocs/op +Benchmark_ToUpperBytes/large-lower/fiber-12 44765679 26.92 ns/op 64 B/op 1 allocs/op +Benchmark_ToUpperBytes/large-lower/fiber/unsafe-12 100000000 13.68 ns/op 0 B/op 0 allocs/op +Benchmark_ToUpperBytes/large-lower/default-12 14464340 110.7 ns/op 64 B/op 1 allocs/op +Benchmark_ToUpperBytes/large-upper/fiber-12 100000000 11.98 ns/op 0 B/op 0 allocs/op +Benchmark_ToUpperBytes/large-upper/fiber/unsafe-12 83808488 13.94 ns/op 0 B/op 0 allocs/op +Benchmark_ToUpperBytes/large-upper/default-12 13142096 87.35 ns/op 64 B/op 1 allocs/op +Benchmark_ToUpperBytes/large-mixed/fiber-12 33038661 32.75 ns/op 64 B/op 1 allocs/op +Benchmark_ToUpperBytes/large-mixed/fiber/unsafe-12 100000000 10.93 ns/op 0 B/op 0 allocs/op +Benchmark_ToUpperBytes/large-mixed/default-12 15034422 98.27 ns/op 64 B/op 1 allocs/op +Benchmark_ToUpper/empty/fiber-12 595298628 2.309 ns/op 0 B/op 0 allocs/op +Benchmark_ToUpper/empty/fiber/unsafe-12 595273404 2.021 ns/op 0 B/op 0 allocs/op +Benchmark_ToUpper/empty/default-12 636980288 1.883 ns/op 0 B/op 0 allocs/op +Benchmark_ToUpper/http-get/fiber-12 97025577 12.40 ns/op 3 B/op 1 allocs/op +Benchmark_ToUpper/http-get/fiber/unsafe-12 244711635 4.857 ns/op 0 B/op 0 allocs/op +Benchmark_ToUpper/http-get/default-12 59790234 19.54 ns/op 8 B/op 1 allocs/op +Benchmark_ToUpper/http-get-upper/fiber-12 383218539 3.056 ns/op 0 B/op 0 allocs/op +Benchmark_ToUpper/http-get-upper/fiber/unsafe-12 247851331 4.864 ns/op 0 B/op 0 allocs/op +Benchmark_ToUpper/http-get-upper/default-12 223044249 5.182 ns/op 0 B/op 0 allocs/op +Benchmark_ToUpper/header-content-type-mixed/fiber-12 52628502 24.13 ns/op 48 B/op 1 allocs/op +Benchmark_ToUpper/header-content-type-mixed/fiber/unsafe-12 127726341 9.233 ns/op 0 B/op 0 allocs/op +Benchmark_ToUpper/header-content-type-mixed/default-12 11549816 104.0 ns/op 48 B/op 1 allocs/op +Benchmark_ToUpper/large-lower/fiber-12 42409070 26.04 ns/op 64 B/op 1 allocs/op +Benchmark_ToUpper/large-lower/fiber/unsafe-12 100000000 11.00 ns/op 0 B/op 0 allocs/op +Benchmark_ToUpper/large-lower/default-12 7051911 169.0 ns/op 64 B/op 1 allocs/op +Benchmark_ToUpper/large-upper/fiber-12 123837582 9.590 ns/op 0 B/op 0 allocs/op +Benchmark_ToUpper/large-upper/fiber/unsafe-12 100000000 10.83 ns/op 0 B/op 0 allocs/op +Benchmark_ToUpper/large-upper/default-12 19115356 61.51 ns/op 0 B/op 0 allocs/op +Benchmark_ToUpper/large-mixed/fiber-12 45872143 27.77 ns/op 64 B/op 1 allocs/op +Benchmark_ToUpper/large-mixed/fiber/unsafe-12 100000000 11.00 ns/op 0 B/op 0 allocs/op +Benchmark_ToUpper/large-mixed/default-12 5927710 203.1 ns/op 64 B/op 1 allocs/op +Benchmark_ToLower/empty/fiber-12 613625554 1.952 ns/op 0 B/op 0 allocs/op +Benchmark_ToLower/empty/fiber/unsafe-12 572670608 1.989 ns/op 0 B/op 0 allocs/op +Benchmark_ToLower/empty/default-12 644769141 1.863 ns/op 0 B/op 0 allocs/op +Benchmark_ToLower/http-get/fiber-12 395302272 3.034 ns/op 0 B/op 0 allocs/op +Benchmark_ToLower/http-get/fiber/unsafe-12 252231990 4.813 ns/op 0 B/op 0 allocs/op +Benchmark_ToLower/http-get/default-12 284202345 4.219 ns/op 0 B/op 0 allocs/op +Benchmark_ToLower/http-get-upper/fiber-12 100000000 12.08 ns/op 3 B/op 1 allocs/op +Benchmark_ToLower/http-get-upper/fiber/unsafe-12 252859507 4.816 ns/op 0 B/op 0 allocs/op +Benchmark_ToLower/http-get-upper/default-12 60415860 19.54 ns/op 8 B/op 1 allocs/op +Benchmark_ToLower/header-content-type-mixed/fiber-12 53446660 22.49 ns/op 48 B/op 1 allocs/op +Benchmark_ToLower/header-content-type-mixed/fiber/unsafe-12 131152108 9.153 ns/op 0 B/op 0 allocs/op +Benchmark_ToLower/header-content-type-mixed/default-12 18039788 66.79 ns/op 48 B/op 1 allocs/op +Benchmark_ToLower/large-lower/fiber-12 120227584 9.982 ns/op 0 B/op 0 allocs/op +Benchmark_ToLower/large-lower/fiber/unsafe-12 100000000 10.68 ns/op 0 B/op 0 allocs/op +Benchmark_ToLower/large-lower/default-12 24070928 48.79 ns/op 0 B/op 0 allocs/op +Benchmark_ToLower/large-upper/fiber-12 44699118 25.92 ns/op 64 B/op 1 allocs/op +Benchmark_ToLower/large-upper/fiber/unsafe-12 100000000 10.74 ns/op 0 B/op 0 allocs/op +Benchmark_ToLower/large-upper/default-12 7075200 170.0 ns/op 64 B/op 1 allocs/op +Benchmark_ToLower/large-mixed/fiber-12 46426453 26.01 ns/op 64 B/op 1 allocs/op +Benchmark_ToLower/large-mixed/fiber/unsafe-12 100000000 10.74 ns/op 0 B/op 0 allocs/op +Benchmark_ToLower/large-mixed/default-12 5682778 204.3 ns/op 64 B/op 1 allocs/op # Add Trailing Slash -Benchmark_AddTrailingSlashBytes/empty-12 1000000000 0.6968 ns/op 0 B/op 0 allocs/op -Benchmark_AddTrailingSlashBytes/slash-only-12 1000000000 1.072 ns/op 0 B/op 0 allocs/op -Benchmark_AddTrailingSlashBytes/short-no-slash-12 87295214 16.10 ns/op 4 B/op 1 allocs/op -Benchmark_AddTrailingSlashBytes/short-with-slash-12 1000000000 1.055 ns/op 0 B/op 0 allocs/op -Benchmark_AddTrailingSlashBytes/path-no-slash-12 49061860 28.34 ns/op 16 B/op 1 allocs/op -Benchmark_AddTrailingSlashBytes/path-with-slash-12 1000000000 1.053 ns/op 0 B/op 0 allocs/op -Benchmark_AddTrailingSlashString/empty-12 1000000000 0.2986 ns/op 0 B/op 0 allocs/op -Benchmark_AddTrailingSlashString/slash-only-12 1000000000 0.4552 ns/op 0 B/op 0 allocs/op -Benchmark_AddTrailingSlashString/short-no-slash-12 100000000 11.43 ns/op 4 B/op 1 allocs/op -Benchmark_AddTrailingSlashString/short-with-slash-12 1000000000 0.4569 ns/op 0 B/op 0 allocs/op -Benchmark_AddTrailingSlashString/path-no-slash-12 84621513 14.61 ns/op 16 B/op 1 allocs/op -Benchmark_AddTrailingSlashString/path-with-slash-12 1000000000 0.4529 ns/op 0 B/op 0 allocs/op +Benchmark_AddTrailingSlashBytes/empty-12 1000000000 0.5857 ns/op 0 B/op 0 allocs/op +Benchmark_AddTrailingSlashBytes/slash-only-12 1000000000 0.8694 ns/op 0 B/op 0 allocs/op +Benchmark_AddTrailingSlashBytes/short-no-slash-12 100000000 11.65 ns/op 4 B/op 1 allocs/op +Benchmark_AddTrailingSlashBytes/short-with-slash-12 1000000000 0.8867 ns/op 0 B/op 0 allocs/op +Benchmark_AddTrailingSlashBytes/path-no-slash-12 93543546 13.36 ns/op 16 B/op 1 allocs/op +Benchmark_AddTrailingSlashBytes/path-with-slash-12 1000000000 0.9011 ns/op 0 B/op 0 allocs/op +Benchmark_AddTrailingSlashString/empty-12 1000000000 0.2926 ns/op 0 B/op 0 allocs/op +Benchmark_AddTrailingSlashString/slash-only-12 1000000000 0.4482 ns/op 0 B/op 0 allocs/op +Benchmark_AddTrailingSlashString/short-no-slash-12 100000000 11.37 ns/op 4 B/op 1 allocs/op +Benchmark_AddTrailingSlashString/short-with-slash-12 1000000000 0.4502 ns/op 0 B/op 0 allocs/op +Benchmark_AddTrailingSlashString/path-no-slash-12 82427726 14.41 ns/op 16 B/op 1 allocs/op +Benchmark_AddTrailingSlashString/path-with-slash-12 1000000000 0.4529 ns/op 0 B/op 0 allocs/op # EqualFold -Benchmark_EqualFoldBytes/fiber-12 24560449 43.80 ns/op 0 B/op 0 allocs/op -Benchmark_EqualFoldBytes/default-12 14990294 84.85 ns/op 0 B/op 0 allocs/op -Benchmark_EqualFold/fiber-12 31785342 44.77 ns/op 0 B/op 0 allocs/op -Benchmark_EqualFold/default-12 12664594 87.50 ns/op 0 B/op 0 allocs/op +Benchmark_EqualFoldBytes/fiber-12 67368261 18.48 ns/op 0 B/op 0 allocs/op +Benchmark_EqualFoldBytes/default-12 17774803 65.91 ns/op 0 B/op 0 allocs/op +Benchmark_EqualFold/fiber-12 80501566 14.75 ns/op 0 B/op 0 allocs/op +Benchmark_EqualFold/default-12 18314365 65.96 ns/op 0 B/op 0 allocs/op + +# Search +Benchmark_IndexAny2/7B/swar-12 282163779 4.297 ns/op 0 B/op 0 allocs/op +Benchmark_IndexAny2/7B/scalar-12 314553402 3.826 ns/op 0 B/op 0 allocs/op +Benchmark_IndexAny2/7B/stdlib-indexany-12 50085909 23.97 ns/op 0 B/op 0 allocs/op +Benchmark_IndexAny2/8B/swar-12 522780714 2.289 ns/op 0 B/op 0 allocs/op +Benchmark_IndexAny2/8B/scalar-12 271494799 4.206 ns/op 0 B/op 0 allocs/op +Benchmark_IndexAny2/8B/stdlib-indexany-12 44831599 26.78 ns/op 0 B/op 0 allocs/op +Benchmark_IndexAny2/16B/swar-12 393245086 3.047 ns/op 0 B/op 0 allocs/op +Benchmark_IndexAny2/16B/scalar-12 168476984 7.117 ns/op 0 B/op 0 allocs/op +Benchmark_IndexAny2/16B/stdlib-indexany-12 100000000 10.03 ns/op 0 B/op 0 allocs/op +Benchmark_IndexAny2/32B/swar-12 252199587 4.802 ns/op 0 B/op 0 allocs/op +Benchmark_IndexAny2/32B/scalar-12 84105762 14.27 ns/op 0 B/op 0 allocs/op +Benchmark_IndexAny2/32B/stdlib-indexany-12 70291048 17.37 ns/op 0 B/op 0 allocs/op +Benchmark_IndexAny2/64B/swar-12 144335962 8.290 ns/op 0 B/op 0 allocs/op +Benchmark_IndexAny2/64B/scalar-12 42694686 28.60 ns/op 0 B/op 0 allocs/op +Benchmark_IndexAny2/64B/stdlib-indexany-12 37615540 32.23 ns/op 0 B/op 0 allocs/op +Benchmark_IndexAny2/512B/swar-12 20231538 59.71 ns/op 0 B/op 0 allocs/op +Benchmark_IndexAny2/512B/scalar-12 5071586 233.6 ns/op 0 B/op 0 allocs/op +Benchmark_IndexAny2/512B/stdlib-indexany-12 4448119 274.2 ns/op 0 B/op 0 allocs/op +Benchmark_IndexAny3/7B/swar-12 221889592 5.397 ns/op 0 B/op 0 allocs/op +Benchmark_IndexAny3/7B/scalar-12 240859849 4.977 ns/op 0 B/op 0 allocs/op +Benchmark_IndexAny3/8B/swar-12 445742876 2.689 ns/op 0 B/op 0 allocs/op +Benchmark_IndexAny3/8B/scalar-12 211981612 5.620 ns/op 0 B/op 0 allocs/op +Benchmark_IndexAny3/16B/swar-12 326475568 3.739 ns/op 0 B/op 0 allocs/op +Benchmark_IndexAny3/16B/scalar-12 100000000 10.31 ns/op 0 B/op 0 allocs/op +Benchmark_IndexAny3/32B/swar-12 196365920 6.112 ns/op 0 B/op 0 allocs/op +Benchmark_IndexAny3/32B/scalar-12 60021255 19.81 ns/op 0 B/op 0 allocs/op +Benchmark_IndexAny3/64B/swar-12 100000000 10.98 ns/op 0 B/op 0 allocs/op +Benchmark_IndexAny3/64B/scalar-12 31180405 38.97 ns/op 0 B/op 0 allocs/op +Benchmark_IndexAny3/512B/swar-12 15466316 79.22 ns/op 0 B/op 0 allocs/op +Benchmark_IndexAny3/512B/scalar-12 3911382 307.1 ns/op 0 B/op 0 allocs/op +Benchmark_IndexFold/miss-8B/swar-12 332497509 3.634 ns/op 0 B/op 0 allocs/op +Benchmark_IndexFold/miss-8B/scalar-12 491493494 2.408 ns/op 0 B/op 0 allocs/op +Benchmark_IndexFold/miss-32B/swar-12 149769112 7.928 ns/op 0 B/op 0 allocs/op +Benchmark_IndexFold/miss-32B/scalar-12 44041342 27.13 ns/op 0 B/op 0 allocs/op +Benchmark_IndexFold/hit-32B/swar-12 138732252 8.758 ns/op 0 B/op 0 allocs/op +Benchmark_IndexFold/hit-32B/scalar-12 33871633 30.73 ns/op 0 B/op 0 allocs/op +Benchmark_IndexFold/hit-tail/swar-12 100000000 12.34 ns/op 0 B/op 0 allocs/op +Benchmark_IndexFold/hit-tail/scalar-12 16138168 75.39 ns/op 0 B/op 0 allocs/op +Benchmark_IndexFold/miss-64B/swar-12 100000000 11.37 ns/op 0 B/op 0 allocs/op +Benchmark_IndexFold/miss-64B/scalar-12 17902330 67.78 ns/op 0 B/op 0 allocs/op +Benchmark_IndexFold/miss-512B/swar-12 17640939 67.65 ns/op 0 B/op 0 allocs/op +Benchmark_IndexFold/miss-512B/scalar-12 2211582 544.4 ns/op 0 B/op 0 allocs/op +Benchmark_IndexFold/long-hit-64B/swar-12 100000000 11.58 ns/op 0 B/op 0 allocs/op +Benchmark_IndexFold/long-hit-64B/scalar-12 23906326 51.33 ns/op 0 B/op 0 allocs/op +Benchmark_IndexFold/long-miss-64B/swar-12 100000000 11.33 ns/op 0 B/op 0 allocs/op +Benchmark_IndexFold/long-miss-64B/scalar-12 23553600 50.27 ns/op 0 B/op 0 allocs/op + +# ASCII +Benchmark_IsASCII/7B/swar-12 238699563 5.001 ns/op 0 B/op 0 allocs/op +Benchmark_IsASCII/7B/scalar-12 292669958 4.064 ns/op 0 B/op 0 allocs/op +Benchmark_IsASCII/8B/swar-12 439961722 2.687 ns/op 0 B/op 0 allocs/op +Benchmark_IsASCII/8B/scalar-12 274732192 4.364 ns/op 0 B/op 0 allocs/op +Benchmark_IsASCII/16B/swar-12 367179319 3.255 ns/op 0 B/op 0 allocs/op +Benchmark_IsASCII/16B/scalar-12 179331987 6.706 ns/op 0 B/op 0 allocs/op +Benchmark_IsASCII/32B/swar-12 368345228 3.271 ns/op 0 B/op 0 allocs/op +Benchmark_IsASCII/32B/scalar-12 100000000 11.62 ns/op 0 B/op 0 allocs/op +Benchmark_IsASCII/64B/swar-12 265505815 4.486 ns/op 0 B/op 0 allocs/op +Benchmark_IsASCII/64B/scalar-12 57864440 21.33 ns/op 0 B/op 0 allocs/op +Benchmark_IsASCII/512B/swar-12 47664915 25.14 ns/op 0 B/op 0 allocs/op +Benchmark_IsASCII/512B/scalar-12 7081790 169.5 ns/op 0 B/op 0 allocs/op +Benchmark_IndexNonQuotable/7B/swar-12 142234436 8.424 ns/op 0 B/op 0 allocs/op +Benchmark_IndexNonQuotable/7B/scalar-12 142394628 8.174 ns/op 0 B/op 0 allocs/op +Benchmark_IndexNonQuotable/8B/swar-12 401721262 3.099 ns/op 0 B/op 0 allocs/op +Benchmark_IndexNonQuotable/8B/scalar-12 138047568 8.654 ns/op 0 B/op 0 allocs/op +Benchmark_IndexNonQuotable/16B/swar-12 244592613 5.059 ns/op 0 B/op 0 allocs/op +Benchmark_IndexNonQuotable/16B/scalar-12 75413396 15.94 ns/op 0 B/op 0 allocs/op +Benchmark_IndexNonQuotable/32B/swar-12 138857455 8.875 ns/op 0 B/op 0 allocs/op +Benchmark_IndexNonQuotable/32B/scalar-12 39539425 30.18 ns/op 0 B/op 0 allocs/op +Benchmark_IndexNonQuotable/64B/swar-12 75193269 16.46 ns/op 0 B/op 0 allocs/op +Benchmark_IndexNonQuotable/64B/scalar-12 20898807 57.81 ns/op 0 B/op 0 allocs/op +Benchmark_IndexNonQuotable/512B/swar-12 9634008 124.9 ns/op 0 B/op 0 allocs/op +Benchmark_IndexNonQuotable/512B/scalar-12 2619062 460.6 ns/op 0 B/op 0 allocs/op # Trim -Benchmark_TrimRight/fiber-12 485636703 2.319 ns/op 0 B/op 0 allocs/op -Benchmark_TrimRight/default-12 389052968 2.984 ns/op 0 B/op 0 allocs/op -Benchmark_TrimRightBytes/fiber-12 570778065 2.153 ns/op 0 B/op 0 allocs/op -Benchmark_TrimRightBytes/default-12 354338642 3.378 ns/op 0 B/op 0 allocs/op -Benchmark_TrimLeft/fiber-12 546707935 2.161 ns/op 0 B/op 0 allocs/op -Benchmark_TrimLeft/default-12 395816548 3.839 ns/op 0 B/op 0 allocs/op -Benchmark_TrimLeftBytes/fiber-12 517814619 2.408 ns/op 0 B/op 0 allocs/op -Benchmark_TrimLeftBytes/default-12 344487759 3.479 ns/op 0 B/op 0 allocs/op -Benchmark_Trim/fiber-12 268123645 4.985 ns/op 0 B/op 0 allocs/op -Benchmark_Trim/default-12 216317569 5.603 ns/op 0 B/op 0 allocs/op -Benchmark_Trim/default.trimspace-12 196718382 6.164 ns/op 0 B/op 0 allocs/op -Benchmark_TrimBytes/fiber-12 276413652 4.682 ns/op 0 B/op 0 allocs/op -Benchmark_TrimBytes/default-12 206646734 6.416 ns/op 0 B/op 0 allocs/op -Benchmark_TrimBytes/default.trimspace-12 180688819 7.050 ns/op 0 B/op 0 allocs/op -Benchmark_TrimSpace/fiber/empty-12 1000000000 0.3595 ns/op 0 B/op 0 allocs/op -Benchmark_TrimSpace/default/empty-12 530890448 2.519 ns/op 0 B/op 0 allocs/op -Benchmark_TrimSpace/fiber/spaces-12 274174633 3.941 ns/op 761.16 MB/s 0 B/op 0 allocs/op -Benchmark_TrimSpace/default/spaces-12 287224635 4.902 ns/op 611.98 MB/s 0 B/op 0 allocs/op -Benchmark_TrimSpace/fiber/ascii-word-12 291975805 4.577 ns/op 1966.40 MB/s 0 B/op 0 allocs/op -Benchmark_TrimSpace/default/ascii-word-12 205111491 5.559 ns/op 1618.98 MB/s 0 B/op 0 allocs/op -Benchmark_TrimSpace/fiber/auth-header-bearer-12 249115078 5.141 ns/op 4668.43 MB/s 0 B/op 0 allocs/op -Benchmark_TrimSpace/default/auth-header-bearer-12 181133806 6.330 ns/op 3791.28 MB/s 0 B/op 0 allocs/op -Benchmark_TrimSpace/fiber/auth-header-basic-12 358262827 3.202 ns/op 11868.28 MB/s 0 B/op 0 allocs/op -Benchmark_TrimSpace/default/auth-header-basic-12 246771914 4.861 ns/op 7817.71 MB/s 0 B/op 0 allocs/op -Benchmark_TrimSpace/fiber/accept-encoding-12 327337672 3.649 ns/op 5754.64 MB/s 0 B/op 0 allocs/op -Benchmark_TrimSpace/default/accept-encoding-12 263390455 4.551 ns/op 4614.63 MB/s 0 B/op 0 allocs/op -Benchmark_TrimSpace/fiber/content-type-12 328083764 3.669 ns/op 5451.76 MB/s 0 B/op 0 allocs/op -Benchmark_TrimSpace/default/content-type-12 263841824 4.557 ns/op 4388.98 MB/s 0 B/op 0 allocs/op -Benchmark_TrimSpace/fiber/x-forwarded-for-12 439685796 2.752 ns/op 10175.38 MB/s 0 B/op 0 allocs/op -Benchmark_TrimSpace/default/x-forwarded-for-12 281075425 4.245 ns/op 6595.73 MB/s 0 B/op 0 allocs/op -Benchmark_TrimSpace/fiber/query-params-12 327527677 3.652 ns/op 5476.47 MB/s 0 B/op 0 allocs/op -Benchmark_TrimSpace/default/query-params-12 263637592 4.546 ns/op 4399.23 MB/s 0 B/op 0 allocs/op -Benchmark_TrimSpace/fiber/ascii-long-12 263431845 4.665 ns/op 21864.72 MB/s 0 B/op 0 allocs/op -Benchmark_TrimSpace/default/ascii-long-12 196392247 6.130 ns/op 16640.29 MB/s 0 B/op 0 allocs/op -Benchmark_TrimSpace/fiber/no-trim-12 1000000000 0.6094 ns/op 8205.02 MB/s 0 B/op 0 allocs/op -Benchmark_TrimSpace/default/no-trim-12 438738540 2.760 ns/op 1811.78 MB/s 0 B/op 0 allocs/op -Benchmark_TrimSpace/fiber/mixed-whitespace-12 280189737 4.289 ns/op 3963.47 MB/s 0 B/op 0 allocs/op -Benchmark_TrimSpace/default/mixed-whitespace-12 220052497 5.464 ns/op 3111.01 MB/s 0 B/op 0 allocs/op -Benchmark_TrimSpaceBytes/fiber/empty-12 1000000000 0.3036 ns/op 0 B/op 0 allocs/op -Benchmark_TrimSpaceBytes/default/empty-12 492696795 2.426 ns/op 0 B/op 0 allocs/op -Benchmark_TrimSpaceBytes/fiber/spaces-12 390392758 3.090 ns/op 970.86 MB/s 0 B/op 0 allocs/op -Benchmark_TrimSpaceBytes/default/spaces-12 294485332 4.060 ns/op 738.89 MB/s 0 B/op 0 allocs/op -Benchmark_TrimSpaceBytes/fiber/ascii-word-12 326114242 3.662 ns/op 2457.47 MB/s 0 B/op 0 allocs/op -Benchmark_TrimSpaceBytes/default/ascii-word-12 245688716 4.901 ns/op 1836.35 MB/s 0 B/op 0 allocs/op -Benchmark_TrimSpaceBytes/fiber/auth-header-bearer-12 281842446 4.254 ns/op 5642.35 MB/s 0 B/op 0 allocs/op -Benchmark_TrimSpaceBytes/default/auth-header-bearer-12 208275072 5.765 ns/op 4162.93 MB/s 0 B/op 0 allocs/op -Benchmark_TrimSpaceBytes/fiber/auth-header-basic-12 375564568 3.186 ns/op 11925.46 MB/s 0 B/op 0 allocs/op -Benchmark_TrimSpaceBytes/default/auth-header-basic-12 232178205 5.161 ns/op 7362.63 MB/s 0 B/op 0 allocs/op -Benchmark_TrimSpaceBytes/fiber/accept-encoding-12 327044280 3.674 ns/op 5715.36 MB/s 0 B/op 0 allocs/op -Benchmark_TrimSpaceBytes/default/accept-encoding-12 246186018 4.882 ns/op 4301.08 MB/s 0 B/op 0 allocs/op -Benchmark_TrimSpaceBytes/fiber/content-type-12 327820933 3.673 ns/op 5445.58 MB/s 0 B/op 0 allocs/op -Benchmark_TrimSpaceBytes/default/content-type-12 247571902 4.851 ns/op 4123.23 MB/s 0 B/op 0 allocs/op -Benchmark_TrimSpaceBytes/fiber/x-forwarded-for-12 433509044 2.763 ns/op 10132.97 MB/s 0 B/op 0 allocs/op -Benchmark_TrimSpaceBytes/default/x-forwarded-for-12 263725153 4.551 ns/op 6153.07 MB/s 0 B/op 0 allocs/op -Benchmark_TrimSpaceBytes/fiber/query-params-12 327897222 3.666 ns/op 5455.18 MB/s 0 B/op 0 allocs/op -Benchmark_TrimSpaceBytes/default/query-params-12 246765888 4.859 ns/op 4115.96 MB/s 0 B/op 0 allocs/op -Benchmark_TrimSpaceBytes/fiber/ascii-long-12 262128422 4.558 ns/op 22377.17 MB/s 0 B/op 0 allocs/op -Benchmark_TrimSpaceBytes/default/ascii-long-12 188152813 6.363 ns/op 16030.46 MB/s 0 B/op 0 allocs/op -Benchmark_TrimSpaceBytes/fiber/no-trim-12 1000000000 0.6211 ns/op 8050.53 MB/s 0 B/op 0 allocs/op -Benchmark_TrimSpaceBytes/default/no-trim-12 395639230 3.036 ns/op 1646.73 MB/s 0 B/op 0 allocs/op -Benchmark_TrimSpaceBytes/fiber/mixed-whitespace-12 282314606 4.243 ns/op 4007.05 MB/s 0 B/op 0 allocs/op -Benchmark_TrimSpaceBytes/default/mixed-whitespace-12 207869355 5.766 ns/op 2948.57 MB/s 0 B/op 0 allocs/op +Benchmark_TrimRight/fiber-12 587360972 2.043 ns/op 0 B/op 0 allocs/op +Benchmark_TrimRight/default-12 417142952 2.887 ns/op 0 B/op 0 allocs/op +Benchmark_TrimRightBytes/fiber-12 590828253 2.067 ns/op 0 B/op 0 allocs/op +Benchmark_TrimRightBytes/default-12 374548395 3.236 ns/op 0 B/op 0 allocs/op +Benchmark_TrimLeft/fiber-12 590822072 2.030 ns/op 0 B/op 0 allocs/op +Benchmark_TrimLeft/default-12 408184784 2.967 ns/op 0 B/op 0 allocs/op +Benchmark_TrimLeftBytes/fiber-12 592875732 2.033 ns/op 0 B/op 0 allocs/op +Benchmark_TrimLeftBytes/default-12 405921434 2.967 ns/op 0 B/op 0 allocs/op +Benchmark_Trim/fiber-12 317625432 3.758 ns/op 0 B/op 0 allocs/op +Benchmark_Trim/default-12 250173384 4.735 ns/op 0 B/op 0 allocs/op +Benchmark_Trim/default.trimspace-12 241883282 5.022 ns/op 0 B/op 0 allocs/op +Benchmark_TrimBytes/fiber-12 308885211 3.858 ns/op 0 B/op 0 allocs/op +Benchmark_TrimBytes/default-12 254064188 4.802 ns/op 0 B/op 0 allocs/op +Benchmark_TrimBytes/default.trimspace-12 224231778 5.330 ns/op 0 B/op 0 allocs/op +Benchmark_TrimSpace/fiber/empty-12 1000000000 0.3017 ns/op 0 B/op 0 allocs/op +Benchmark_TrimSpace/default/empty-12 583064172 2.074 ns/op 0 B/op 0 allocs/op +Benchmark_TrimSpace/fiber/spaces-12 387354229 3.059 ns/op 0 B/op 0 allocs/op +Benchmark_TrimSpace/default/spaces-12 320059388 3.651 ns/op 0 B/op 0 allocs/op +Benchmark_TrimSpace/fiber/ascii-word-12 345078337 3.535 ns/op 0 B/op 0 allocs/op +Benchmark_TrimSpace/default/ascii-word-12 270603267 4.465 ns/op 0 B/op 0 allocs/op +Benchmark_TrimSpace/fiber/auth-header-bearer-12 291494109 4.141 ns/op 0 B/op 0 allocs/op +Benchmark_TrimSpace/default/auth-header-bearer-12 224087944 5.329 ns/op 0 B/op 0 allocs/op +Benchmark_TrimSpace/fiber/auth-header-basic-12 390765345 3.047 ns/op 0 B/op 0 allocs/op +Benchmark_TrimSpace/default/auth-header-basic-12 258943531 4.718 ns/op 0 B/op 0 allocs/op +Benchmark_TrimSpace/fiber/accept-encoding-12 344369745 3.490 ns/op 0 B/op 0 allocs/op +Benchmark_TrimSpace/default/accept-encoding-12 277203638 4.347 ns/op 0 B/op 0 allocs/op +Benchmark_TrimSpace/fiber/content-type-12 344263705 3.506 ns/op 0 B/op 0 allocs/op +Benchmark_TrimSpace/default/content-type-12 276213367 4.343 ns/op 0 B/op 0 allocs/op +Benchmark_TrimSpace/fiber/x-forwarded-for-12 460119685 2.653 ns/op 0 B/op 0 allocs/op +Benchmark_TrimSpace/default/x-forwarded-for-12 296468840 4.058 ns/op 0 B/op 0 allocs/op +Benchmark_TrimSpace/fiber/query-params-12 330053276 3.520 ns/op 0 B/op 0 allocs/op +Benchmark_TrimSpace/default/query-params-12 275688495 4.352 ns/op 0 B/op 0 allocs/op +Benchmark_TrimSpace/fiber/ascii-long-12 275511898 4.342 ns/op 0 B/op 0 allocs/op +Benchmark_TrimSpace/default/ascii-long-12 206143018 5.807 ns/op 0 B/op 0 allocs/op +Benchmark_TrimSpace/fiber/no-trim-12 1000000000 0.5914 ns/op 0 B/op 0 allocs/op +Benchmark_TrimSpace/default/no-trim-12 451842741 2.634 ns/op 0 B/op 0 allocs/op +Benchmark_TrimSpace/fiber/mixed-whitespace-12 296083767 4.054 ns/op 0 B/op 0 allocs/op +Benchmark_TrimSpace/default/mixed-whitespace-12 224007750 5.294 ns/op 0 B/op 0 allocs/op +Benchmark_TrimSpaceBytes/fiber/empty-12 1000000000 0.2914 ns/op 0 B/op 0 allocs/op +Benchmark_TrimSpaceBytes/default/empty-12 519488766 2.352 ns/op 0 B/op 0 allocs/op +Benchmark_TrimSpaceBytes/fiber/spaces-12 410959255 2.966 ns/op 0 B/op 0 allocs/op +Benchmark_TrimSpaceBytes/default/spaces-12 315602949 3.827 ns/op 0 B/op 0 allocs/op +Benchmark_TrimSpaceBytes/fiber/ascii-word-12 341217429 3.519 ns/op 0 B/op 0 allocs/op +Benchmark_TrimSpaceBytes/default/ascii-word-12 247799318 4.667 ns/op 0 B/op 0 allocs/op +Benchmark_TrimSpaceBytes/fiber/auth-header-bearer-12 295130076 4.182 ns/op 0 B/op 0 allocs/op +Benchmark_TrimSpaceBytes/default/auth-header-bearer-12 209162235 5.685 ns/op 0 B/op 0 allocs/op +Benchmark_TrimSpaceBytes/fiber/auth-header-basic-12 393366796 3.053 ns/op 0 B/op 0 allocs/op +Benchmark_TrimSpaceBytes/default/auth-header-basic-12 240882009 4.930 ns/op 0 B/op 0 allocs/op +Benchmark_TrimSpaceBytes/fiber/accept-encoding-12 343673244 3.512 ns/op 0 B/op 0 allocs/op +Benchmark_TrimSpaceBytes/default/accept-encoding-12 250962042 4.642 ns/op 0 B/op 0 allocs/op +Benchmark_TrimSpaceBytes/fiber/content-type-12 344382758 3.516 ns/op 0 B/op 0 allocs/op +Benchmark_TrimSpaceBytes/default/content-type-12 250622116 4.693 ns/op 0 B/op 0 allocs/op +Benchmark_TrimSpaceBytes/fiber/x-forwarded-for-12 459435145 2.621 ns/op 0 B/op 0 allocs/op +Benchmark_TrimSpaceBytes/default/x-forwarded-for-12 276595178 4.359 ns/op 0 B/op 0 allocs/op +Benchmark_TrimSpaceBytes/fiber/query-params-12 341144192 3.526 ns/op 0 B/op 0 allocs/op +Benchmark_TrimSpaceBytes/default/query-params-12 255843174 4.873 ns/op 0 B/op 0 allocs/op +Benchmark_TrimSpaceBytes/fiber/ascii-long-12 270183530 4.445 ns/op 0 B/op 0 allocs/op +Benchmark_TrimSpaceBytes/default/ascii-long-12 189740618 6.335 ns/op 0 B/op 0 allocs/op +Benchmark_TrimSpaceBytes/fiber/no-trim-12 1000000000 0.5969 ns/op 0 B/op 0 allocs/op +Benchmark_TrimSpaceBytes/default/no-trim-12 406072189 2.941 ns/op 0 B/op 0 allocs/op +Benchmark_TrimSpaceBytes/fiber/mixed-whitespace-12 289382116 4.057 ns/op 0 B/op 0 allocs/op +Benchmark_TrimSpaceBytes/default/mixed-whitespace-12 218559462 5.493 ns/op 0 B/op 0 allocs/op # Convert -Benchmark_ConvertToBytes/fiber-12 303731499 3.947 ns/op 0 B/op 0 allocs/op -Benchmark_ToString/int-12 497704682 2.406 ns/op 0 B/op 0 allocs/op -Benchmark_ToString/int8-12 607933017 1.975 ns/op 0 B/op 0 allocs/op -Benchmark_ToString/int16-12 484205890 2.481 ns/op 0 B/op 0 allocs/op -Benchmark_ToString/int32-12 490413688 2.459 ns/op 0 B/op 0 allocs/op -Benchmark_ToString/int64-12 500168806 2.405 ns/op 0 B/op 0 allocs/op -Benchmark_ToString/uint-12 568876189 2.106 ns/op 0 B/op 0 allocs/op -Benchmark_ToString/uint8-12 609816264 1.975 ns/op 0 B/op 0 allocs/op -Benchmark_ToString/uint16-12 567892762 2.102 ns/op 0 B/op 0 allocs/op -Benchmark_ToString/uint32-12 570461389 2.123 ns/op 0 B/op 0 allocs/op -Benchmark_ToString/uint64-12 567259215 2.119 ns/op 0 B/op 0 allocs/op -Benchmark_ToString/string-12 606332637 1.993 ns/op 0 B/op 0 allocs/op -Benchmark_ToString/[]uint8-12 93052707 12.31 ns/op 16 B/op 1 allocs/op -Benchmark_ToString/bool-12 603432777 1.995 ns/op 0 B/op 0 allocs/op -Benchmark_ToString/float32-12 25012396 48.04 ns/op 4 B/op 1 allocs/op -Benchmark_ToString/float64-12 17169336 70.51 ns/op 4 B/op 1 allocs/op -Benchmark_ToString/time.Time-12 12940731 92.84 ns/op 24 B/op 1 allocs/op -Benchmark_ToString/time.Time#01-12 12885784 93.52 ns/op 24 B/op 1 allocs/op -Benchmark_ToString/[]string-12 51672447 23.11 ns/op 16 B/op 1 allocs/op -Benchmark_ToString/[]int-12 51177982 23.30 ns/op 8 B/op 1 allocs/op -Benchmark_ToString/[2]int-12 29876820 38.88 ns/op 16 B/op 1 allocs/op -Benchmark_ToString/[][]int-12 8826847 136.3 ns/op 112 B/op 6 allocs/op -Benchmark_ToString/[]interface_{}-12 9783631 120.3 ns/op 72 B/op 3 allocs/op -Benchmark_ToString/utils.MyStringer-12 398624744 3.015 ns/op 0 B/op 0 allocs/op -Benchmark_ToString/utils.CustomType-12 11562967 104.5 ns/op 16 B/op 1 allocs/op -Benchmark_ToString_concurrency/int-12 1000000000 0.2675 ns/op 0 B/op 0 allocs/op -Benchmark_ToString_concurrency/int8-12 1000000000 0.2241 ns/op 0 B/op 0 allocs/op -Benchmark_ToString_concurrency/int16-12 1000000000 0.2761 ns/op 0 B/op 0 allocs/op -Benchmark_ToString_concurrency/int32-12 1000000000 0.2719 ns/op 0 B/op 0 allocs/op -Benchmark_ToString_concurrency/int64-12 1000000000 0.2673 ns/op 0 B/op 0 allocs/op -Benchmark_ToString_concurrency/uint-12 1000000000 0.2339 ns/op 0 B/op 0 allocs/op -Benchmark_ToString_concurrency/uint8-12 1000000000 0.2289 ns/op 0 B/op 0 allocs/op -Benchmark_ToString_concurrency/uint16-12 1000000000 0.2354 ns/op 0 B/op 0 allocs/op -Benchmark_ToString_concurrency/uint32-12 1000000000 0.2309 ns/op 0 B/op 0 allocs/op -Benchmark_ToString_concurrency/uint64-12 1000000000 0.2364 ns/op 0 B/op 0 allocs/op -Benchmark_ToString_concurrency/string-12 1000000000 0.2189 ns/op 0 B/op 0 allocs/op -Benchmark_ToString_concurrency/[]uint8-12 205632634 5.758 ns/op 16 B/op 1 allocs/op -Benchmark_ToString_concurrency/bool-12 1000000000 0.2346 ns/op 0 B/op 0 allocs/op -Benchmark_ToString_concurrency/float32-12 187598121 6.133 ns/op 4 B/op 1 allocs/op -Benchmark_ToString_concurrency/float64-12 135170138 8.719 ns/op 4 B/op 1 allocs/op -Benchmark_ToString_concurrency/time.Time-12 74157042 18.63 ns/op 24 B/op 1 allocs/op -Benchmark_ToString_concurrency/time.Time#01-12 61104981 20.85 ns/op 24 B/op 1 allocs/op -Benchmark_ToString_concurrency/[]string-12 148502100 7.790 ns/op 16 B/op 1 allocs/op -Benchmark_ToString_concurrency/[]int-12 230634176 5.118 ns/op 8 B/op 1 allocs/op -Benchmark_ToString_concurrency/[2]int-12 133293684 9.173 ns/op 16 B/op 1 allocs/op -Benchmark_ToString_concurrency/[][]int-12 22382804 54.81 ns/op 112 B/op 6 allocs/op -Benchmark_ToString_concurrency/[]interface_{}-12 33572145 36.32 ns/op 72 B/op 3 allocs/op -Benchmark_ToString_concurrency/utils.MyStringer-12 1000000000 0.3800 ns/op 0 B/op 0 allocs/op -Benchmark_ToString_concurrency/utils.CustomType-12 54238104 23.27 ns/op 16 B/op 1 allocs/op -Benchmark_UnsafeBytes/unsafe-12 1000000000 0.5654 ns/op 0 B/op 0 allocs/op -Benchmark_UnsafeBytes/default-12 88676498 13.68 ns/op 16 B/op 1 allocs/op -Benchmark_UnsafeString/unsafe-12 1000000000 0.3530 ns/op 0 B/op 0 allocs/op -Benchmark_UnsafeString/default-12 100000000 11.92 ns/op 16 B/op 1 allocs/op -Benchmark_ByteSize/0-12 400988882 3.004 ns/op 0 B/op 0 allocs/op -Benchmark_ByteSize/1-12 68500806 17.65 ns/op 16 B/op 1 allocs/op -Benchmark_ByteSize/500-12 60281438 19.95 ns/op 16 B/op 1 allocs/op -Benchmark_ByteSize/1024-12 59684172 19.67 ns/op 16 B/op 1 allocs/op -Benchmark_ByteSize/1126-12 53318622 26.05 ns/op 16 B/op 1 allocs/op -Benchmark_ByteSize/1048576-12 59837815 21.27 ns/op 16 B/op 1 allocs/op -Benchmark_ByteSize/1153024-12 52797439 22.84 ns/op 16 B/op 1 allocs/op -Benchmark_ByteSize/1073741824-12 60002750 19.76 ns/op 16 B/op 1 allocs/op -Benchmark_ByteSize/1180696576-12 52817191 22.15 ns/op 16 B/op 1 allocs/op -Benchmark_ByteSize/1099511627776-12 64727100 19.55 ns/op 16 B/op 1 allocs/op -Benchmark_ByteSize/1209033293824-12 54228812 21.65 ns/op 16 B/op 1 allocs/op -Benchmark_ByteSize/1125899906842624-12 64025749 18.28 ns/op 16 B/op 1 allocs/op -Benchmark_ByteSize/1238050092875776-12 57805672 22.45 ns/op 16 B/op 1 allocs/op -Benchmark_ByteSize/1152921504606846976-12 64201592 18.70 ns/op 16 B/op 1 allocs/op -Benchmark_ByteSize/1267763295104794624-12 58673847 21.37 ns/op 16 B/op 1 allocs/op +Benchmark_ConvertToBytes/fiber-12 320332576 3.787 ns/op 0 B/op 0 allocs/op +Benchmark_ToString/int-12 499429904 2.382 ns/op 0 B/op 0 allocs/op +Benchmark_ToString/int8-12 614406423 1.965 ns/op 0 B/op 0 allocs/op +Benchmark_ToString/int16-12 486644316 2.463 ns/op 0 B/op 0 allocs/op +Benchmark_ToString/int32-12 495227163 2.422 ns/op 0 B/op 0 allocs/op +Benchmark_ToString/int64-12 502362236 2.429 ns/op 0 B/op 0 allocs/op +Benchmark_ToString/uint-12 561693333 2.101 ns/op 0 B/op 0 allocs/op +Benchmark_ToString/uint8-12 611239028 1.965 ns/op 0 B/op 0 allocs/op +Benchmark_ToString/uint16-12 573383422 2.127 ns/op 0 B/op 0 allocs/op +Benchmark_ToString/uint32-12 575723191 2.093 ns/op 0 B/op 0 allocs/op +Benchmark_ToString/uint64-12 575901750 2.089 ns/op 0 B/op 0 allocs/op +Benchmark_ToString/string-12 613909396 1.959 ns/op 0 B/op 0 allocs/op +Benchmark_ToString/[]uint8-12 96832432 12.11 ns/op 16 B/op 1 allocs/op +Benchmark_ToString/bool-12 608058547 1.990 ns/op 0 B/op 0 allocs/op +Benchmark_ToString/float32-12 23195016 47.11 ns/op 4 B/op 1 allocs/op +Benchmark_ToString/float64-12 17204126 70.24 ns/op 4 B/op 1 allocs/op +Benchmark_ToString/time.Time-12 13103935 91.85 ns/op 24 B/op 1 allocs/op +Benchmark_ToString/time.Time#01-12 13198113 91.22 ns/op 24 B/op 1 allocs/op +Benchmark_ToString/[]string-12 65187865 18.35 ns/op 16 B/op 1 allocs/op +Benchmark_ToString/[]int-12 54417859 21.53 ns/op 8 B/op 1 allocs/op +Benchmark_ToString/[2]int-12 32691942 36.57 ns/op 16 B/op 1 allocs/op +Benchmark_ToString/[][]int-12 9382754 128.8 ns/op 112 B/op 6 allocs/op +Benchmark_ToString/[]interface_{}-12 10584483 114.5 ns/op 72 B/op 3 allocs/op +Benchmark_ToString/utils.MyStringer-12 365979882 3.277 ns/op 0 B/op 0 allocs/op +Benchmark_ToString/utils.CustomType-12 11649330 102.5 ns/op 16 B/op 1 allocs/op +Benchmark_ToString_concurrency/int-12 1000000000 0.2619 ns/op 0 B/op 0 allocs/op +Benchmark_ToString_concurrency/int8-12 1000000000 0.2202 ns/op 0 B/op 0 allocs/op +Benchmark_ToString_concurrency/int16-12 1000000000 0.2708 ns/op 0 B/op 0 allocs/op +Benchmark_ToString_concurrency/int32-12 1000000000 0.2658 ns/op 0 B/op 0 allocs/op +Benchmark_ToString_concurrency/int64-12 1000000000 0.2658 ns/op 0 B/op 0 allocs/op +Benchmark_ToString_concurrency/uint-12 1000000000 0.2281 ns/op 0 B/op 0 allocs/op +Benchmark_ToString_concurrency/uint8-12 1000000000 0.2223 ns/op 0 B/op 0 allocs/op +Benchmark_ToString_concurrency/uint16-12 1000000000 0.2396 ns/op 0 B/op 0 allocs/op +Benchmark_ToString_concurrency/uint32-12 1000000000 0.2273 ns/op 0 B/op 0 allocs/op +Benchmark_ToString_concurrency/uint64-12 1000000000 0.2271 ns/op 0 B/op 0 allocs/op +Benchmark_ToString_concurrency/string-12 1000000000 0.2117 ns/op 0 B/op 0 allocs/op +Benchmark_ToString_concurrency/[]uint8-12 213842515 5.718 ns/op 16 B/op 1 allocs/op +Benchmark_ToString_concurrency/bool-12 1000000000 0.2118 ns/op 0 B/op 0 allocs/op +Benchmark_ToString_concurrency/float32-12 201081819 6.011 ns/op 4 B/op 1 allocs/op +Benchmark_ToString_concurrency/float64-12 142000966 8.799 ns/op 4 B/op 1 allocs/op +Benchmark_ToString_concurrency/time.Time-12 71451783 18.04 ns/op 24 B/op 1 allocs/op +Benchmark_ToString_concurrency/time.Time#01-12 69313578 17.74 ns/op 24 B/op 1 allocs/op +Benchmark_ToString_concurrency/[]string-12 187564670 6.455 ns/op 16 B/op 1 allocs/op +Benchmark_ToString_concurrency/[]int-12 262707805 4.498 ns/op 8 B/op 1 allocs/op +Benchmark_ToString_concurrency/[2]int-12 129274200 8.777 ns/op 16 B/op 1 allocs/op +Benchmark_ToString_concurrency/[][]int-12 22638411 52.65 ns/op 112 B/op 6 allocs/op +Benchmark_ToString_concurrency/[]interface_{}-12 34120837 35.36 ns/op 72 B/op 3 allocs/op +Benchmark_ToString_concurrency/utils.MyStringer-12 1000000000 0.4259 ns/op 0 B/op 0 allocs/op +Benchmark_ToString_concurrency/utils.CustomType-12 54806094 25.95 ns/op 16 B/op 1 allocs/op +Benchmark_UnsafeBytes/unsafe-12 1000000000 0.5658 ns/op 0 B/op 0 allocs/op +Benchmark_UnsafeBytes/default-12 88407558 13.50 ns/op 16 B/op 1 allocs/op +Benchmark_UnsafeString/unsafe-12 1000000000 0.3545 ns/op 0 B/op 0 allocs/op +Benchmark_UnsafeString/default-12 100000000 12.09 ns/op 16 B/op 1 allocs/op +Benchmark_ByteSize/0-12 395954607 3.023 ns/op 0 B/op 0 allocs/op +Benchmark_ByteSize/1-12 65295756 18.15 ns/op 16 B/op 1 allocs/op +Benchmark_ByteSize/500-12 58264801 20.92 ns/op 16 B/op 1 allocs/op +Benchmark_ByteSize/1024-12 60886531 19.80 ns/op 16 B/op 1 allocs/op +Benchmark_ByteSize/1126-12 53409986 22.69 ns/op 16 B/op 1 allocs/op +Benchmark_ByteSize/1048576-12 60969927 19.41 ns/op 16 B/op 1 allocs/op +Benchmark_ByteSize/1153024-12 53647869 22.12 ns/op 16 B/op 1 allocs/op +Benchmark_ByteSize/1073741824-12 63792180 19.05 ns/op 16 B/op 1 allocs/op +Benchmark_ByteSize/1180696576-12 54560540 22.02 ns/op 16 B/op 1 allocs/op +Benchmark_ByteSize/1099511627776-12 64080169 18.85 ns/op 16 B/op 1 allocs/op +Benchmark_ByteSize/1209033293824-12 52957434 22.01 ns/op 16 B/op 1 allocs/op +Benchmark_ByteSize/1125899906842624-12 65629659 18.33 ns/op 16 B/op 1 allocs/op +Benchmark_ByteSize/1238050092875776-12 56535770 21.73 ns/op 16 B/op 1 allocs/op +Benchmark_ByteSize/1152921504606846976-12 64569356 18.56 ns/op 16 B/op 1 allocs/op +Benchmark_ByteSize/1267763295104794624-12 56481996 21.10 ns/op 16 B/op 1 allocs/op # Format and Append -Benchmark_FormatUint/small/fiber-12 616120275 1.968 ns/op 0 B/op 0 allocs/op -Benchmark_FormatUint/small/strconv-12 597079038 1.990 ns/op 0 B/op 0 allocs/op -Benchmark_FormatUint/medium/fiber-12 61883050 18.90 ns/op 16 B/op 1 allocs/op -Benchmark_FormatUint/medium/strconv-12 60313885 20.38 ns/op 16 B/op 1 allocs/op -Benchmark_FormatUint/large/fiber-12 47939197 25.36 ns/op 24 B/op 1 allocs/op -Benchmark_FormatUint/large/strconv-12 44694955 26.49 ns/op 24 B/op 1 allocs/op -Benchmark_FormatInt/small_pos/fiber-12 608629350 1.963 ns/op 0 B/op 0 allocs/op -Benchmark_FormatInt/small_pos/strconv-12 618271995 1.956 ns/op 0 B/op 0 allocs/op -Benchmark_FormatInt/small_neg/fiber-12 626947920 1.919 ns/op 0 B/op 0 allocs/op -Benchmark_FormatInt/small_neg/strconv-12 87661094 14.05 ns/op 3 B/op 1 allocs/op -Benchmark_FormatInt/medium_pos/fiber-12 55510044 24.13 ns/op 16 B/op 1 allocs/op -Benchmark_FormatInt/medium_pos/strconv-12 49636088 20.89 ns/op 16 B/op 1 allocs/op -Benchmark_FormatInt/medium_neg/fiber-12 63894786 19.05 ns/op 16 B/op 1 allocs/op -Benchmark_FormatInt/medium_neg/strconv-12 62000552 19.78 ns/op 16 B/op 1 allocs/op -Benchmark_FormatInt/large_pos/fiber-12 47706525 25.50 ns/op 24 B/op 1 allocs/op -Benchmark_FormatInt/large_pos/strconv-12 45759099 26.59 ns/op 24 B/op 1 allocs/op -Benchmark_FormatInt/large_neg/fiber-12 47631805 25.46 ns/op 24 B/op 1 allocs/op -Benchmark_FormatInt/large_neg/strconv-12 45561183 26.65 ns/op 24 B/op 1 allocs/op -Benchmark_FormatUint32/fiber-12 62901873 19.08 ns/op 16 B/op 1 allocs/op -Benchmark_FormatUint32/strconv-12 59485326 20.61 ns/op 16 B/op 1 allocs/op -Benchmark_FormatInt32/fiber-12 61375447 19.29 ns/op 16 B/op 1 allocs/op -Benchmark_FormatInt32/strconv-12 60683575 19.99 ns/op 16 B/op 1 allocs/op -Benchmark_FormatUint16/fiber-12 80310759 15.03 ns/op 5 B/op 1 allocs/op -Benchmark_FormatUint16/strconv-12 74569866 15.74 ns/op 5 B/op 1 allocs/op -Benchmark_FormatInt16/fiber-12 76845693 15.44 ns/op 8 B/op 1 allocs/op -Benchmark_FormatInt16/strconv-12 78253000 15.80 ns/op 8 B/op 1 allocs/op -Benchmark_FormatUint8/fiber-12 604374918 1.973 ns/op 0 B/op 0 allocs/op -Benchmark_FormatUint8/strconv-12 82805967 14.56 ns/op 3 B/op 1 allocs/op -Benchmark_FormatInt8/fiber-12 610502032 1.969 ns/op 0 B/op 0 allocs/op -Benchmark_FormatInt8/strconv-12 82919455 14.59 ns/op 4 B/op 1 allocs/op -Benchmark_AppendUint/fiber-12 130580040 9.204 ns/op 0 B/op 0 allocs/op -Benchmark_AppendUint/strconv-12 100000000 10.15 ns/op 0 B/op 0 allocs/op -Benchmark_AppendInt/small_neg/fiber-12 363979753 3.293 ns/op 0 B/op 0 allocs/op -Benchmark_AppendInt/small_neg/strconv-12 212234758 5.689 ns/op 0 B/op 0 allocs/op -Benchmark_AppendInt/medium_neg/fiber-12 125316576 9.624 ns/op 0 B/op 0 allocs/op -Benchmark_AppendInt/medium_neg/strconv-12 122066809 9.835 ns/op 0 B/op 0 allocs/op +Benchmark_FormatUint/small/fiber-12 607527520 1.966 ns/op 0 B/op 0 allocs/op +Benchmark_FormatUint/small/strconv-12 607521366 1.973 ns/op 0 B/op 0 allocs/op +Benchmark_FormatUint/medium/fiber-12 64427509 19.04 ns/op 16 B/op 1 allocs/op +Benchmark_FormatUint/medium/strconv-12 59566404 20.42 ns/op 16 B/op 1 allocs/op +Benchmark_FormatUint/large/fiber-12 45395149 26.16 ns/op 24 B/op 1 allocs/op +Benchmark_FormatUint/large/strconv-12 45620366 26.38 ns/op 24 B/op 1 allocs/op +Benchmark_FormatInt/small_pos/fiber-12 608898928 1.963 ns/op 0 B/op 0 allocs/op +Benchmark_FormatInt/small_pos/strconv-12 598721480 1.976 ns/op 0 B/op 0 allocs/op +Benchmark_FormatInt/small_neg/fiber-12 616958124 1.946 ns/op 0 B/op 0 allocs/op +Benchmark_FormatInt/small_neg/strconv-12 87181050 13.77 ns/op 3 B/op 1 allocs/op +Benchmark_FormatInt/medium_pos/fiber-12 63105722 19.12 ns/op 16 B/op 1 allocs/op +Benchmark_FormatInt/medium_pos/strconv-12 57454753 20.70 ns/op 16 B/op 1 allocs/op +Benchmark_FormatInt/medium_neg/fiber-12 63631222 19.10 ns/op 16 B/op 1 allocs/op +Benchmark_FormatInt/medium_neg/strconv-12 61296942 20.17 ns/op 16 B/op 1 allocs/op +Benchmark_FormatInt/large_pos/fiber-12 48604558 25.08 ns/op 24 B/op 1 allocs/op +Benchmark_FormatInt/large_pos/strconv-12 45605844 26.25 ns/op 24 B/op 1 allocs/op +Benchmark_FormatInt/large_neg/fiber-12 47388217 25.09 ns/op 24 B/op 1 allocs/op +Benchmark_FormatInt/large_neg/strconv-12 45871998 26.10 ns/op 24 B/op 1 allocs/op +Benchmark_FormatUint32/fiber-12 63452196 18.63 ns/op 16 B/op 1 allocs/op +Benchmark_FormatUint32/strconv-12 59485942 20.08 ns/op 16 B/op 1 allocs/op +Benchmark_FormatInt32/fiber-12 63030724 18.98 ns/op 16 B/op 1 allocs/op +Benchmark_FormatInt32/strconv-12 61887302 19.69 ns/op 16 B/op 1 allocs/op +Benchmark_FormatUint16/fiber-12 80149611 14.48 ns/op 5 B/op 1 allocs/op +Benchmark_FormatUint16/strconv-12 77022440 15.43 ns/op 5 B/op 1 allocs/op +Benchmark_FormatInt16/fiber-12 79013646 15.23 ns/op 8 B/op 1 allocs/op +Benchmark_FormatInt16/strconv-12 79695165 15.24 ns/op 8 B/op 1 allocs/op +Benchmark_FormatUint8/fiber-12 599811685 1.947 ns/op 0 B/op 0 allocs/op +Benchmark_FormatUint8/strconv-12 84144096 14.18 ns/op 3 B/op 1 allocs/op +Benchmark_FormatInt8/fiber-12 630717244 1.985 ns/op 0 B/op 0 allocs/op +Benchmark_FormatInt8/strconv-12 83826201 14.24 ns/op 4 B/op 1 allocs/op +Benchmark_AppendUint/fiber-12 130817422 9.139 ns/op 0 B/op 0 allocs/op +Benchmark_AppendUint/strconv-12 100000000 10.08 ns/op 0 B/op 0 allocs/op +Benchmark_AppendInt/small_neg/fiber-12 369512403 3.266 ns/op 0 B/op 0 allocs/op +Benchmark_AppendInt/small_neg/strconv-12 213341739 5.627 ns/op 0 B/op 0 allocs/op +Benchmark_AppendInt/medium_neg/fiber-12 125937435 9.531 ns/op 0 B/op 0 allocs/op +Benchmark_AppendInt/medium_neg/strconv-12 122490632 9.791 ns/op 0 B/op 0 allocs/op # Token -Benchmark_GenerateSecureToken/16_bytes-12 4395446 268.0 ns/op 24 B/op 1 allocs/op -Benchmark_GenerateSecureToken/32_bytes-12 4308816 277.5 ns/op 48 B/op 1 allocs/op -Benchmark_TokenGenerators/UUIDv4-12 4115958 294.5 ns/op 64 B/op 2 allocs/op -Benchmark_TokenGenerators/SecureToken-12 4320008 278.1 ns/op 48 B/op 1 allocs/op +Benchmark_GenerateSecureToken/16_bytes-12 4565527 258.6 ns/op 24 B/op 1 allocs/op +Benchmark_GenerateSecureToken/32_bytes-12 4306404 280.8 ns/op 48 B/op 1 allocs/op +Benchmark_TokenGenerators/UUIDv4-12 4019139 288.2 ns/op 64 B/op 2 allocs/op +Benchmark_TokenGenerators/SecureToken-12 4360036 276.9 ns/op 48 B/op 1 allocs/op # HTTP -Benchmark_GetMIME/fiber-12 22006587 54.74 ns/op 0 B/op 0 allocs/op -Benchmark_GetMIME/default-12 17412228 69.29 ns/op 0 B/op 0 allocs/op -Benchmark_ParseVendorSpecificContentType/vendorContentType-12 125887742 9.981 ns/op 0 B/op 0 allocs/op -Benchmark_ParseVendorSpecificContentType/defaultContentType-12 353516896 3.504 ns/op 0 B/op 0 allocs/op -Benchmark_StatusMessage/fiber-12 1000000000 0.3850 ns/op 0 B/op 0 allocs/op -Benchmark_StatusMessage/default-12 431016290 2.751 ns/op 0 B/op 0 allocs/op +Benchmark_GetMIME/fiber-12 22321272 53.90 ns/op 0 B/op 0 allocs/op +Benchmark_GetMIME/default-12 17492530 68.46 ns/op 0 B/op 0 allocs/op +Benchmark_ParseVendorSpecificContentType/vendorContentType-12 125467813 9.619 ns/op 0 B/op 0 allocs/op +Benchmark_ParseVendorSpecificContentType/defaultContentType-12 404169172 2.974 ns/op 0 B/op 0 allocs/op +Benchmark_StatusMessage/fiber-12 1000000000 0.3349 ns/op 0 B/op 0 allocs/op +Benchmark_StatusMessage/default-12 460456902 2.610 ns/op 0 B/op 0 allocs/op # IP -Benchmark_IsIPv4/fiber-12 80343021 15.43 ns/op 0 B/op 0 allocs/op -Benchmark_IsIPv4/default-12 53110760 22.82 ns/op 0 B/op 0 allocs/op -Benchmark_IsIPv6/fiber-12 27125079 44.82 ns/op 0 B/op 0 allocs/op -Benchmark_IsIPv6/default-12 20017320 60.60 ns/op 0 B/op 0 allocs/op +Benchmark_IsIPv4/fiber-12 80408070 14.58 ns/op 0 B/op 0 allocs/op +Benchmark_IsIPv4/default-12 54025154 21.99 ns/op 0 B/op 0 allocs/op +Benchmark_IsIPv6/fiber-12 28283431 42.67 ns/op 0 B/op 0 allocs/op +Benchmark_IsIPv6/default-12 20747964 58.18 ns/op 0 B/op 0 allocs/op # Parse -Benchmark_ParseUint/fiber-12 170572611 7.031 ns/op 0 B/op 0 allocs/op -Benchmark_ParseUint/fiber_bytes-12 161515281 7.414 ns/op 0 B/op 0 allocs/op -Benchmark_ParseUint/default-12 84878630 13.91 ns/op 0 B/op 0 allocs/op -Benchmark_ParseInt/fiber-12 188326305 6.554 ns/op 0 B/op 0 allocs/op -Benchmark_ParseInt/fiber_bytes-12 177401347 6.791 ns/op 0 B/op 0 allocs/op -Benchmark_ParseInt/default-12 74426298 16.02 ns/op 0 B/op 0 allocs/op -Benchmark_ParseInt32/fiber-12 152689100 7.792 ns/op 0 B/op 0 allocs/op -Benchmark_ParseInt32/fiber_bytes-12 143480342 8.350 ns/op 0 B/op 0 allocs/op -Benchmark_ParseInt32/default-12 75226464 15.95 ns/op 0 B/op 0 allocs/op -Benchmark_ParseInt16/fiber-12 233907660 5.214 ns/op 0 B/op 0 allocs/op -Benchmark_ParseInt16/fiber_bytes-12 218961453 5.362 ns/op 0 B/op 0 allocs/op -Benchmark_ParseInt16/default-12 100000000 11.20 ns/op 0 B/op 0 allocs/op -Benchmark_ParseInt8/fiber-12 277644391 4.368 ns/op 0 B/op 0 allocs/op -Benchmark_ParseInt8/fiber_bytes-12 255406502 4.720 ns/op 0 B/op 0 allocs/op -Benchmark_ParseInt8/default-12 137303502 8.716 ns/op 0 B/op 0 allocs/op -Benchmark_ParseUint32/fiber-12 168541228 7.201 ns/op 0 B/op 0 allocs/op -Benchmark_ParseUint32/fiber_bytes-12 160750947 7.499 ns/op 0 B/op 0 allocs/op -Benchmark_ParseUint32/default-12 87199530 13.95 ns/op 0 B/op 0 allocs/op -Benchmark_ParseUint16/fiber-12 259066075 4.625 ns/op 0 B/op 0 allocs/op -Benchmark_ParseUint16/fiber_bytes-12 249345403 4.822 ns/op 0 B/op 0 allocs/op -Benchmark_ParseUint16/default-12 132290673 9.031 ns/op 0 B/op 0 allocs/op -Benchmark_ParseUint8/fiber-12 346359704 3.473 ns/op 0 B/op 0 allocs/op -Benchmark_ParseUint8/fiber_bytes-12 296839494 4.125 ns/op 0 B/op 0 allocs/op -Benchmark_ParseUint8/default-12 180975388 6.673 ns/op 0 B/op 0 allocs/op -Benchmark_ParseFloat64/fiber-12 84649861 14.23 ns/op 0 B/op 0 allocs/op -Benchmark_ParseFloat64/fiber_bytes-12 83656969 14.19 ns/op 0 B/op 0 allocs/op -Benchmark_ParseFloat64/default-12 48787262 24.61 ns/op 0 B/op 0 allocs/op -Benchmark_ParseFloat32/fiber-12 78740156 15.25 ns/op 0 B/op 0 allocs/op -Benchmark_ParseFloat32/fiber_bytes-12 78525037 15.15 ns/op 0 B/op 0 allocs/op -Benchmark_ParseFloat32/default-12 45575605 26.21 ns/op 0 B/op 0 allocs/op +Benchmark_ParseUint/fiber-12 236748204 5.049 ns/op 0 B/op 0 allocs/op +Benchmark_ParseUint/fiber_bytes-12 224650773 5.348 ns/op 0 B/op 0 allocs/op +Benchmark_ParseUint/default-12 88588122 13.75 ns/op 0 B/op 0 allocs/op +Benchmark_ParseUint_DigitRuns/6digit-12 207540178 5.769 ns/op 0 B/op 0 allocs/op +Benchmark_ParseUint_DigitRuns/8digit-12 222360716 5.403 ns/op 0 B/op 0 allocs/op +Benchmark_ParseUint_DigitRuns/12digit-12 156132950 7.699 ns/op 0 B/op 0 allocs/op +Benchmark_ParseUint_DigitRuns/19digit-12 135049720 8.880 ns/op 0 B/op 0 allocs/op +Benchmark_ParseUint_DigitRuns/1digit-12 338642533 3.553 ns/op 0 B/op 0 allocs/op +Benchmark_ParseUint_DigitRuns/4digit-12 212370570 5.672 ns/op 0 B/op 0 allocs/op +Benchmark_ParseInt/fiber-12 299791800 3.981 ns/op 0 B/op 0 allocs/op +Benchmark_ParseInt/fiber_bytes-12 288714712 4.165 ns/op 0 B/op 0 allocs/op +Benchmark_ParseInt/default-12 76370292 15.48 ns/op 0 B/op 0 allocs/op +Benchmark_ParseInt32/fiber-12 200451391 5.988 ns/op 0 B/op 0 allocs/op +Benchmark_ParseInt32/fiber_bytes-12 201629558 5.956 ns/op 0 B/op 0 allocs/op +Benchmark_ParseInt32/default-12 78384832 15.71 ns/op 0 B/op 0 allocs/op +Benchmark_ParseInt16/fiber-12 220670613 5.462 ns/op 0 B/op 0 allocs/op +Benchmark_ParseInt16/fiber_bytes-12 220175068 5.430 ns/op 0 B/op 0 allocs/op +Benchmark_ParseInt16/default-12 100000000 10.71 ns/op 0 B/op 0 allocs/op +Benchmark_ParseInt8/fiber-12 277948545 4.279 ns/op 0 B/op 0 allocs/op +Benchmark_ParseInt8/fiber_bytes-12 264784368 4.566 ns/op 0 B/op 0 allocs/op +Benchmark_ParseInt8/default-12 142184748 8.373 ns/op 0 B/op 0 allocs/op +Benchmark_ParseUint32/fiber-12 238916116 5.025 ns/op 0 B/op 0 allocs/op +Benchmark_ParseUint32/fiber_bytes-12 222286592 5.409 ns/op 0 B/op 0 allocs/op +Benchmark_ParseUint32/default-12 90395479 13.33 ns/op 0 B/op 0 allocs/op +Benchmark_ParseUint16/fiber-12 251398184 4.828 ns/op 0 B/op 0 allocs/op +Benchmark_ParseUint16/fiber_bytes-12 248772012 4.838 ns/op 0 B/op 0 allocs/op +Benchmark_ParseUint16/default-12 137015901 8.788 ns/op 0 B/op 0 allocs/op +Benchmark_ParseUint8/fiber-12 360430984 3.427 ns/op 0 B/op 0 allocs/op +Benchmark_ParseUint8/fiber_bytes-12 327526336 3.659 ns/op 0 B/op 0 allocs/op +Benchmark_ParseUint8/default-12 181904056 6.438 ns/op 0 B/op 0 allocs/op +Benchmark_ParseFloat64/fiber-12 82912768 14.76 ns/op 0 B/op 0 allocs/op +Benchmark_ParseFloat64/fiber_bytes-12 95692504 12.68 ns/op 0 B/op 0 allocs/op +Benchmark_ParseFloat64/default-12 50109265 25.05 ns/op 0 B/op 0 allocs/op +Benchmark_ParseFloat32/fiber-12 76648135 15.76 ns/op 0 B/op 0 allocs/op +Benchmark_ParseFloat32/fiber_bytes-12 86422119 13.63 ns/op 0 B/op 0 allocs/op +Benchmark_ParseFloat32/default-12 47198646 25.41 ns/op 0 B/op 0 allocs/op # Time -Benchmark_CalculateTimestamp/fiber-12 1000000000 0.3411 ns/op 0 B/op 0 allocs/op -Benchmark_CalculateTimestamp/default-12 36431808 33.04 ns/op 0 B/op 0 allocs/op -Benchmark_CalculateTimestamp/fiber_asserted-12 4388325 271.9 ns/op 10 B/op 2 allocs/op -Benchmark_CalculateTimestamp/default_asserted-12 3753456 303.1 ns/op 8 B/op 2 allocs/op +Benchmark_CalculateTimestamp/fiber-12 1000000000 0.3366 ns/op 0 B/op 0 allocs/op +Benchmark_CalculateTimestamp/default-12 36163686 32.69 ns/op 0 B/op 0 allocs/op +Benchmark_CalculateTimestamp/fiber_asserted-12 4471299 267.8 ns/op 12 B/op 2 allocs/op +Benchmark_CalculateTimestamp/default_asserted-12 3991147 298.7 ns/op 8 B/op 2 allocs/op # XML -Benchmark_GolangXMLEncoder-12 581364 2083 ns/op 4864 B/op 12 allocs/op -Benchmark_DefaultXMLEncoder-12 591445 2080 ns/op 4864 B/op 12 allocs/op -Benchmark_DefaultXMLDecoder-12 326768 3486 ns/op 2862 B/op 57 allocs/op +Benchmark_GolangXMLEncoder-12 574852 2040 ns/op 4864 B/op 12 allocs/op +Benchmark_DefaultXMLEncoder-12 593738 2012 ns/op 4864 B/op 12 allocs/op +Benchmark_DefaultXMLDecoder-12 309031 3876 ns/op 2892 B/op 57 allocs/op ``` See all the benchmarks under Index: parse.go IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== diff --git a/parse.go b/parse.go --- a/parse.go (revision 01f52863bec45ba8ea67c7e26605e1f11b43b9a1) +++ b/parse.go (date 1783800208780) @@ -38,7 +38,11 @@ // At most 19 digits fit here, so two 8-digit SWAR steps plus a // scalar remainder can never overflow before the final range check. // A word with a non-digit lane falls through to the scalar loop, - // which reports the syntax error. + // which reports the syntax error. The body deliberately duplicates + // the parseDigitsBig structure: routing through parseDigitsBig + // instead costs +22% on the 9-digit shape (benchstat -count=10, + // Go 1.25, Apple M2 Pro), mostly digit bookkeeping and the extra + // call frame. var n uint64 i := 0 for ; len(s)-i >= 8; i += 8 { Index: swar/example_test.go IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== diff --git a/swar/example_test.go b/swar/example_test.go new file mode 100644 --- /dev/null (date 1783800984930) +++ b/swar/example_test.go (date 1783800984930) @@ -0,0 +1,63 @@ +package swar_test + +import ( + "fmt" + + "github.com/gofiber/utils/v2/swar" +) + +// ExampleZeroLanes shows the canonical first-match scan: broadcast the +// needle once, scan full words, and finish 8+ byte inputs with one +// overlapping word at len(s)-8. The overlap is safe because lanes before +// the loop's exit index are known non-matching, so the first set lane +// always falls into the new bytes. +func ExampleZeroLanes() { + indexByte := func(s string, c byte) int { + n := len(s) + if n < swar.WordLen { + for i := range n { + if s[i] == c { + return i + } + } + return -1 + } + needle := swar.Broadcast(c) + i := 0 + for ; i+swar.WordLen <= n; i += swar.WordLen { + if m := swar.ZeroLanes(swar.Load8(s, i) ^ needle); m != 0 { + return i + swar.FirstLane(m) + } + } + if i == n { + return -1 + } + if m := swar.ZeroLanes(swar.Load8(s, n-swar.WordLen) ^ needle); m != 0 { + return n - swar.WordLen + swar.FirstLane(m) + } + return -1 + } + + fmt.Println(indexByte("cache-control: no-store", ':')) //nolint:errcheck // example output + fmt.Println(indexByte("etag", ':')) //nolint:errcheck // example output + // Output: + // 13 + // -1 +} + +// ExampleMatchRangeMask classifies one word of input: which lanes hold an +// ASCII digit, and where the first and last digit sit. +func ExampleMatchRangeMask() { + w := swar.Load8("Fiber123", 0) + digits := swar.MatchRangeMask(w, '0', '9') + fmt.Println(swar.FirstLane(digits), swar.LastLane(digits)) //nolint:errcheck // example output + // Output: 5 7 +} + +// ExampleLoad8 shows the little-endian lane order: the byte at the lowest +// index becomes lane 0, the least significant byte of the word. +func ExampleLoad8() { + w := swar.Load8([]byte("ABCDEFGH"), 0) + fmt.Printf("lane0=%c lane7=%c\n", byte(w), byte(w>>56)) //nolint:errcheck // example output + // Output: lane0=A lane7=H +}