chore: optimize string manipulation functions and improve error handling#167
chore: optimize string manipulation functions and improve error handling#167ReneWerner87 merged 10 commits intomasterfrom
Conversation
Summary of ChangesHello @ReneWerner87, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request focuses on enhancing the performance and robustness of various utility functions related to string manipulation and type conversion. The changes aim to minimize memory allocations, streamline string processing, and improve the accuracy of error reporting in parsing routines, leading to a more efficient and reliable codebase. Highlights
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #167 +/- ##
==========================================
+ Coverage 83.31% 84.54% +1.23%
==========================================
Files 11 12 +1
Lines 755 938 +183
==========================================
+ Hits 629 793 +164
- Misses 115 124 +9
- Partials 11 21 +10
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Code Review
This pull request introduces several significant performance optimizations and a critical bug fix across various utility functions. The optimizations in functions like ToLower, ToUpper, and ByteSize effectively reduce allocations. The ToString function is also optimized to handle common types without reflection, and more importantly, it fixes a critical bug where unsigned integers were incorrectly converted to strings. While most changes are positive, I have a concern about disabling the unhandled-error linter in .golangci.yml, which could compromise code quality by hiding potential bugs.
There was a problem hiding this comment.
Pull request overview
This PR aims to optimize string manipulation functions and improve error handling across the utils package. However, several optimization attempts introduce bugs or fail to provide actual performance improvements, and some changes reduce code quality.
Key changes:
- Refactored
ToLowerandToUpperfunctions with loop unrolling (but with performance regressions) - Added a sync.Pool for buffer allocation in
ByteSize(incorrectly implemented) - Expanded
ToStringwith direct handling of pointer and slice types - Simplified error message construction in parsing functions
- Updated linter configuration to accommodate
strings.Builderusage
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 9 comments.
Show a summary per file
| File | Description |
|---|---|
| strings.go | Refactored ToLower/ToUpper with loop unrolling, but changes allocate full string upfront causing performance regression |
| strings_test.go | Removed t.Parallel() calls, eliminating concurrent test execution and slowing down test suite |
| parse.go | Improved error messages by avoiding unnecessary string conversion for empty inputs |
| http.go | Refactored GetMIME for clearer control flow; attempted optimization in ParseVendorSpecificContentType that provides no benefit |
| convert.go | Added sync.Pool for ByteSize (with critical bug in type assertion), expanded ToString with pointer/slice type handling, fixed uint conversion functions |
| common.go | Refactored ConvertToBytes with manual byte scanning that's slower than standard library |
| .golangci.yml | Updated linter config for strings.Builder, but disabled unhandled-error rule entirely instead of targeted exclusions |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
Note Other AI code review bot(s) detectedCodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review. WalkthroughRefactors numeric parsing/formatting and MIME helpers: adds a zero-allocation integer formatter and tests, replaces strconv usage with custom Format/Append helpers across conversions, rewrites byte-size digit/unit detection and parse error semantics, and restructures string tests/benchmarks and MIME normalization. Changes
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes
Possibly related PRs
Suggested labels
Suggested reviewers
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
.golangci.ymlis excluded by!**/*.yml
📒 Files selected for processing (6)
common.go(1 hunks)convert.go(5 hunks)http.go(2 hunks)parse.go(3 hunks)strings.go(1 hunks)strings_test.go(0 hunks)
💤 Files with no reviewable changes (1)
- strings_test.go
🧰 Additional context used
🧬 Code graph analysis (1)
common.go (1)
parse.go (2)
ParseFloat64(252-254)ParseUint(20-22)
🪛 GitHub Actions: Modernize Lint
convert.go
[error] 254-254: for loop can be modernized using range over int
🪛 GitHub Check: modernize
convert.go
[failure] 254-254:
for loop can be modernized using range over int
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: Agent
- GitHub Check: Compare
🔇 Additional comments (12)
parse.go (2)
82-82: Consistent empty string optimization for empty input errors.When the input
sis empty,string(s)would produce""anyway, so settingNum: ""directly avoids an unnecessary conversion. This is a correct micro-optimization applied consistently across all three parsing functions.Also applies to: 125-125, 145-145
128-129: Simplified parseDigits call.Removing the separate index variable and calling
parseDigits(s, 0)directly is a cleaner approach that reduces local state.common.go (2)
138-157: Good refactor: combined backward scan for digit and unit detection.The single backward pass to find both the last digit position and unit prefix position is efficient. The early return for missing digits (line 155-157) is a good defensive check.
162-183: Replaced stdlib calls with internal parsing functions.Using
ParseFloat64andParseUintinstead ofstrconv.ParseFloatandstrconv.ParseUintaligns with the PR's goal of reducing external dependencies. The manual dot detection loop is simple and avoids thestringsimport.http.go (2)
19-41: Clean normalization of extension handling.Computing both
extWithoutDotandextWithDotonce upfront eliminates repeated checks and makes the control flow clearer. The fallback chain (map lookup → mime package → default) is well-structured.
77-82: Reduced allocation with pre-sized buffer.Using a pre-allocated byte slice and
UnsafeStringavoids the allocation from string concatenation. This is a valid optimization for hot paths.strings.go (2)
8-45: Effective single-allocation optimization with early-out for no-op cases.The approach of detecting the first character needing conversion and returning early if none is found eliminates allocations for already-lowercase strings. The loop unrolling at lines 34-39 can improve throughput for longer strings.
48-85: ToUpper mirrors ToLower structure consistently.Same optimization pattern applied symmetrically. The implementation is correct and consistent.
convert.go (4)
18-24: Good use of sync.Pool for buffer reuse.The pool correctly stores a pointer to a slice (
*[]byte) to avoid interface allocation overhead. The initial capacity of 16 bytes is reasonable for the typical output sizes.
96-131: Correct pool usage with copy before return.The
string(buf)calls at lines 107 and 128 correctly create a copy of the buffer contents before returning the buffer to the pool. This ensures the returned string doesn't alias the pooled memory.
148-156: Direct FormatUint for unsigned types.Using
strconv.FormatUintdirectly for unsigned types is more appropriate than going throughItoawhich is designed for signed integers.
208-237: Direct slice handling reduces reflection overhead.Handling
[]stringand[]intexplicitly avoids the reflection path for these common types. The space-separated format matches the reflection-based behavior.
There was a problem hiding this comment.
Actionable comments posted: 0
♻️ Duplicate comments (2)
convert.go (2)
147-156: Unsigned integer conversion now usesFormatUint– correctness fix confirmed.Switching all unsigned cases (
uint,uint8,uint16,uint32,uint64) tostrconv.FormatUint(Lines 147–156) avoids the overflow/incorrect string issues that occur when routing through signed types. This matches the intended domain of these values and fixes the prior bug without changing the public API surface.
176-207: Pointer fast paths are efficient, but nil semantics change for basic pointer types.
- The specialized pointer cases for
*string,*int,*int64,*uint64,*float64, and*bool(Lines 176–207) are efficient and avoid reflection for common cases.- However, they intentionally change nil behavior: e.g.
ToString((*int)(nil))now returns"0"instead of the previous"<nil>"fallback viafmt.Sprint, and similarly(*string)(nil)→"",(*bool)(nil)→"false".If this semantic change is intended, it should be explicitly documented and covered by tests; otherwise, consider returning
"<nil>"(or delegating tofmt.Sprint) for the nil branches to preserve prior behavior.
🧹 Nitpick comments (2)
convert.go (2)
13-24: ByteSize’s sync.Pool usage and buffer lifecycle look correct.
- The
byteSizePoolsetup andGet/Putpattern are sound:bufPtris always initialized (*bufPtr = make(...)) in the fallback path before slicing (Line 100), so there’s no risk of slicing a nil slice.- Converting with
result := string(buf)before returning the buffer to the pool (Lines 107 and 128) correctly avoids aliasing; usingUnsafeStringhere would be unsafe if the buffer is reused.- You’re getting reduced allocations on the
[]bytebacking store while still paying the unavoidablestringcopy, which is a reasonable trade-off for this API.If you want stricter safety, you could replace the
if !okbranch with apanic, since any wrong type coming from this pool would be a programming error, but the current defensive fallback is still correct.Also applies to: 96-103, 107-111, 128-131
208-237: Direct []string and []int formatting is correct and allocation‑aware.
- The specialized handling for
[]stringand[]int(Lines 208–237) matchesfmt.Sprint’s bracketed, space‑separated format ([a b],[]for empty) while avoiding reflection in the hot path.- Using
strings.Builderwith a roughGrowheuristic is fine here; it trades a modest over-approximation for fewer reallocations, and behaves reasonably for nil vs empty slices (len(v) == 0hits the early"[]"return).Looks good as-is; no functional issues spotted.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
convert.go(5 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Compare
🔇 Additional comments (1)
convert.go (1)
241-252: The review comment contains an incorrect primary concern regardingreflect.ValueOf(nil)behavior. Callingrv.Kind()on the zeroreflect.Valuereturned byreflect.ValueOf(nil)does not panic—it safely returnsreflect.Invalid. The current code at line 241 is safe.For
nilarguments, the function already handles them correctly:
reflect.ValueOf(nil)returns a zeroreflect.Valuerv.Kind()returnsreflect.Invalidwithout panicking- Neither the pointer check (line 242) nor the slice/array check (line 245) matches
- Execution falls through to
fmt.Sprint(arg)at line 265, which returns"<nil>"—the same behavior as before the refactorThe other observations are accurate: the
for i := range nsyntax correctly uses Go 1.22+ semantics, and the recursive formatting of slices/arrays could theoretically loop on self-referential structures (though this is a low-probability edge case). Adding an earlynilguard is not necessary to prevent a panic and would be purely stylistic.
There was a problem hiding this comment.
Actionable comments posted: 0
♻️ Duplicate comments (2)
convert.go (1)
155-185: Nil pointer behavior still needs test coverage.This comment echoes a previous review concern: the explicit nil handling for common pointer types (
*string,*int,*int64, etc.) returns type-specific defaults ("","0","false") rather than"<nil>", which differs from how barenilor unhandled pointer types are treated (they fall through tofmt.Sprintand return"<nil>").The code comment indicates this is an intentional optimization to avoid reflection. However, test coverage documenting this behavior is still missing. Consider adding test cases such as:
require.Equal(t, "0", ToString((*int)(nil)))require.Equal(t, "", ToString((*string)(nil)))Based on past reviews, this behavioral change was previously flagged and remains unaddressed.
strings.go (1)
9-15: Consider keeping a zero-allocation fast path for unchanged ASCII inputThis version always allocates and copies
len(b)bytes before mapping throughtoLowerTable, whereas the previous implementation (per summary / earlier feedback) avoided allocation when no bytes changed and only copied once a differing byte was found. For common already-lowercase ASCII inputs this can be a GC and CPU regression. A hybrid approach could scan for the first byte wheretoLowerTable[c] != c, and only then allocate/copy and apply the table from that index onward, returning the originalbif no such byte is found. That preserves the optimization while still using the lookup table on the hot path.
🧹 Nitpick comments (1)
strings.go (1)
20-26: Mirror the ToLower strategy and consider de-duplicating the case-mapping logicThe same “always allocate/copy and map” pattern applies here, with the same trade-offs as in
ToLower. Whatever strategy you choose there (e.g., reintroducing a no-change fast path) should be mirrored here for consistency. Given the bodies are identical except fortoUpperTablevstoLowerTable, you might also extract a small helper likefunc mapASCII(b string, tbl *[256]byte) stringto avoid copy-paste and keep behavior in sync.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
common.go(1 hunks)convert.go(4 hunks)http.go(2 hunks)strings.go(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- common.go
🧰 Additional context used
🧬 Code graph analysis (2)
strings.go (1)
convert.go (1)
UnsafeString(18-23)
convert.go (1)
format.go (10)
AppendUint(88-95)FormatInt(46-55)FormatInt8(83-85)FormatInt16(73-75)FormatInt32(63-65)FormatUint(35-42)FormatUint8(78-80)FormatUint16(68-70)FormatUint32(58-60)FormatBool(110-115)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
- GitHub Check: Build (1.23.x, windows-latest)
- GitHub Check: Build (1.24.x, macos-13)
- GitHub Check: Compare
🔇 Additional comments (6)
convert.go (4)
87-111: LGTM! ByteSize optimization using new AppendUint helper.The switch from
strconv.AppendUintto the newAppendUinthelper is consistent with the PR's optimization goals. The logic correctly handles both the integer-only case (when div == 1) and the fractional case, and the UnsafeString usage is safe sincebufis a local variable.
117-141: LGTM! Critical bug fix and performance optimization for numeric types.The switch to dedicated
Format*helpers (FormatInt, FormatUint, FormatInt8, etc.) correctly addresses the critical overflow bug in the previous implementation where unsigned integers were incorrectly cast to signed types. The new implementation properly usesFormatUintfor unsigned types andFormatIntfor signed types.
187-216: LGTM! Efficient optimization for common slice types.The direct handling of
[]stringand[]intavoids reflection overhead and usesstrings.Builderwith sensible pre-allocation. The space-separated format (e.g.,"[hello world]") is consistent with the reflection-based slice handling below.
220-240: LGTM! Reflection path optimized with modern Go syntax.The improvements correctly:
- Cache the
Kind()result to avoid redundant calls- Use
strings.Builderwith pre-allocation for slice/array formatting- Employ the modern
for i := range nsyntax (Go 1.22+), which addresses the previously flagged lint issueThe logic correctly handles pointers (dereferencing non-nil), slices/arrays (formatted with space-separated elements), and falls back to
fmt.Sprintfor other types.http.go (2)
20-42: GetMIME normalization and fallback chain look correctThe revised flow is tight and preserves expected behavior:
- Empty-string guard avoids any indexing panics.
- Normalizing into
extWithoutDot/extWithDotonce removes redundant checks while handling both"ext"and".ext"forms consistently.- Prioritizing
mimeExtensions[extWithoutDot]beforemime.TypeByExtension(extWithDot)keeps your custom MIME overrides (likejs,xml, etc.) in control and only falls back to the stdlib when not covered by your table.- The final
MIMEOctetStreamfallback gives a consistent default for unknown extensions rather than leaking an empty string for non-empty input.This matches the intended “custom table → stdlib →
application/octet-stream” resolution described in the library context.
77-77: Idiomatic slice expression in ParseVendorSpecificContentTypeSwitching from
working[0:slashIndex+1]toworking[:slashIndex+1]is purely stylistic and idiomatic Go with no behavioral change; the function still correctly reconstructstype/subtypefor vendor-specific content types.
…educed allocations
…v package for improved performance
There was a problem hiding this comment.
Actionable comments posted: 0
♻️ Duplicate comments (1)
convert.go (1)
155-185: Nil pointer behavior change should be documented and tested.The nil pointer handling returns type-specific zero values (
"","0","false") rather than"<nil>"which would be produced by thefmt.Sprintfallback. This is a behavioral change that should be explicitly covered by tests.Consider adding test cases to document this intentional behavior:
// Example test cases for nil pointer handling require.Equal(t, "", ToString((*string)(nil))) require.Equal(t, "0", ToString((*int)(nil))) require.Equal(t, "0", ToString((*int64)(nil))) require.Equal(t, "0", ToString((*uint64)(nil))) require.Equal(t, "0", ToString((*float64)(nil))) require.Equal(t, "false", ToString((*bool)(nil)))Based on past review comment noting this behavioral change needs documentation.
🧹 Nitpick comments (1)
convert.go (1)
186-216: Consider documenting the space-separated slice format.The slice formatting uses space-separated elements (
[a b c]) rather than the comma-separated format typical in Go ([a, b, c]). This is consistent between the direct type cases and the reflection fallback, but the format choice may surprise users expecting standard Go representation.If this is intentional, consider adding a code comment or documentation noting the format.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
convert.go(4 hunks)format.go(1 hunks)format_test.go(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- format_test.go
🧰 Additional context used
🧬 Code graph analysis (1)
convert.go (1)
format.go (9)
AppendUint(88-95)FormatInt(46-55)FormatInt8(83-85)FormatInt16(73-75)FormatInt32(63-65)FormatUint(35-42)FormatUint8(78-80)FormatUint16(68-70)FormatUint32(58-60)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Compare
🔇 Additional comments (8)
convert.go (3)
88-111: LGTM - ByteSize optimization is correct.The switch from
strconv.AppendUintto the customAppendUinthelper is consistent with the performance-oriented approach introduced informat.go. The logic remains sound, andUnsafeStringis appropriate here since the buffer is not reused after conversion.
116-135: LGTM - Integer formatting conversions are correct.All integer types are properly converted using the new formatting helpers. The widening conversions (e.g.,
inttoint64,uinttouint64) are safe and correct for all value ranges.
217-244: LGTM - Reflection fallback is well-structured.The early
kindextraction and the use ofrange n(Go 1.22+ syntax) are correct. The slice/array handling via reflection is consistent with the direct type cases. Nil pointers correctly fall through tofmt.Sprintwhich produces"<nil>".format.go (5)
1-17: LGTM - Small integer cache is well-designed.The precomputed
smallIntscache for values 0-99 is a good optimization that avoids allocations for the most common integer values. Theinit()function correctly populates the cache at startup.
19-31: LGTM - Buffer formatting is correct and efficient.The
formatUintBuffunction correctly handles all uint64 values. The 20-byte buffer is appropriately sized for the maximum uint64 value (20 digits), and the algorithm correctly extracts digits from right to left.
44-55: LGTM - FormatInt correctly handles all int64 values including MinInt64.The implementation correctly handles the edge case of
math.MinInt64(-9223372036854775808) due to two's complement arithmetic. When-noverflows in int64, the subsequentuint64()conversion produces the correct unsigned magnitude (9223372036854775808).
57-85: LGTM - Type-specific wrappers are correct.All wrappers correctly delegate to
FormatUintorFormatIntwith safe widening conversions. This provides a clean API while maintaining the performance benefits of the underlying implementation.
87-107: LGTM - Append functions are correct and consistent.The
AppendUintandAppendIntfunctions mirror the logic of theirFormat*counterparts while efficiently appending to a destination slice. The small integer cache optimization is correctly applied here as well.
…ng custom implementations with standard library functions
|
Comment from CodeRabbit: 155-185: Nil pointer behavior change should be documented and tested.
The nil pointer handling returns type-specific zero values ("", "0", "false") rather than "<nil>" which would be produced by the fmt.Sprint fallback. This is a behavioral change that should be explicitly covered by tests. |
…ve performance for small integers
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (2)
convert_test.go (1)
167-192: Good coverage for the documented nil-pointer behavior change.These tests correctly verify the new type-specific default values for nil pointers, which is a behavioral change from the previous
<nil>fallback. The tests are well-structured and run in parallel.Consider adding similar tests for other pointer types that might be handled by
ToString(e.g.,*float32,*uint,*int32) to ensure comprehensive coverage of nil-pointer edge cases.format.go (1)
194-204: Consider caching small negative integers in AppendInt for consistency.
AppendIntdoesn't usesmallNegIntsfor values in the range -99 to -1, unlikeFormatInt. This means small negative integers incur a buffer allocation and formatting overhead.// AppendInt appends the decimal string representation of n to dst. func AppendInt(dst []byte, n int64) []byte { if n >= 0 { return AppendUint(dst, uint64(n)) } + if n > -100 { + return append(dst, smallNegInts[-n]...) + } var buf [20]byte i := formatUintBuf(&buf, uint64(-n)) i-- buf[i] = '-' return append(dst, buf[i:]...) }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
convert_test.go(1 hunks)format.go(1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
convert_test.go (1)
convert.go (1)
ToString(114-246)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: Build (1.23.x, windows-latest)
- GitHub Check: Compare
🔇 Additional comments (7)
format.go (7)
9-16: LGTM: Cache initialization is correct.The cache initialization correctly populates both positive and negative small integer caches, and appropriately skips index 0 for negative numbers.
18-23: LGTM: Small integer formatting helper is correct.The helper correctly handles single and double-digit numbers using efficient byte arithmetic.
25-37: LGTM: Buffer formatting is efficient and correct.The 20-byte buffer is sufficient for the maximum uint64 value (20 digits), and the digit extraction loop is implemented correctly.
50-69: FormatInt correctly handles math.MinInt64.The conversion
uint64(-n)whenn = math.MinInt64works correctly in Go due to two's complement representation—the overflow wraps to produce the correct unsigned magnitude (9223372036854775808).
71-112: LGTM: 32-bit formatting functions are correct.Buffer sizes are appropriate (10 for uint32, 11 for int32 with sign), and the edge case of
math.MinInt32is handled correctly through unsigned conversion.
114-155: LGTM: 16-bit formatting functions are correct.Buffer sizes and logic are appropriate for the value ranges.
157-182: LGTM: 8-bit formatting handles edge cases correctly.The special case of
math.MinInt8(-128) is handled correctly—the unsigned conversion viauint8(-n)produces 128 due to Go's two's complement bit reinterpretation.
|
@gaby fixed |
|
@ReneWerner87 One more small thing: format.go (1) AppendInt doesn't use smallNegInts for values in the range -99 to -1, unlike FormatInt. This means small negative integers incur a buffer allocation and formatting overhead. |
│ old.txt │ new.txt │ │ sec/op │ sec/op vs base │ _ConvertToBytes/fiber-12 10.075n ± 3% 7.393n ± 0% -26.62% (p=0.002 n=6) _ToString/int-12 2.599n ± 1% 2.663n ± 0% +2.50% (p=0.002 n=6) _ToString/int8-12 2.597n ± 1% 2.668n ± 1% +2.71% (p=0.002 n=6) _ToString/int16-12 2.599n ± 1% 2.667n ± 1% +2.62% (p=0.002 n=6) _ToString/int32-12 2.598n ± 1% 2.665n ± 1% +2.58% (p=0.002 n=6) _ToString/int64-12 2.594n ± 0% 2.667n ± 1% +2.79% (p=0.002 n=6) _ToString/uint-12 2.592n ± 1% 2.074n ± 0% -20.02% (p=0.002 n=6) _ToString/uint8-12 2.591n ± 1% 2.075n ± 0% -19.88% (p=0.002 n=6) _ToString/uint16-12 2.592n ± 1% 2.073n ± 1% -20.02% (p=0.002 n=6) _ToString/uint32-12 2.592n ± 1% 2.075n ± 1% -19.96% (p=0.002 n=6) _ToString/uint64-12 2.594n ± 0% 2.074n ± 1% -20.07% (p=0.002 n=6) _ToString/string-12 1.936n ± 0% 1.944n ± 0% +0.39% (p=0.002 n=6) _ToString/[]uint8-12 12.02n ± 1% 12.11n ± 0% +0.83% (p=0.050 n=6) _ToString/time.Time-12 91.41n ± 1% 91.67n ± 1% +0.29% (p=0.045 n=6) _ToString/time.Time#01-12 90.74n ± 0% 91.27n ± 1% +0.59% (p=0.009 n=6) _ToString/[]string-12 82.20n ± 1% 22.31n ± 1% -72.85% (p=0.002 n=6) _ToString/[]int-12 57.88n ± 0% 23.58n ± 1% -59.26% (p=0.002 n=6) _ToString/[2]int-12 41.93n ± 2% 37.62n ± 1% -10.29% (p=0.002 n=6) _ToString/[][]int-12 228.7n ± 2% 133.2n ± 1% -41.74% (p=0.002 n=6) _ToString/[]interface_{}-12 261.8n ± 1% 118.0n ± 0% -54.92% (p=0.002 n=6) _ToString/utils.MyStringer-12 3.883n ± 2% 2.963n ± 1% -23.69% (p=0.002 n=6) _ByteSize/1-12 17.88n ± 1% 17.37n ± 1% -2.85% (p=0.002 n=6) _ByteSize/500-12 22.49n ± 2% 19.62n ± 1% -12.76% (p=0.002 n=6) _ByteSize/1024-12 19.34n ± 1% 18.96n ± 0% -1.96% (p=0.002 n=6) _ByteSize/1126-12 22.54n ± 1% 21.96n ± 1% -2.57% (p=0.002 n=6) _ByteSize/1048576-12 19.02n ± 1% 18.75n ± 1% -1.45% (p=0.002 n=6) _ByteSize/1153024-12 22.21n ± 0% 21.65n ± 1% -2.50% (p=0.002 n=6) _ByteSize/1073741824-12 18.82n ± 1% 18.36n ± 0% -2.50% (p=0.002 n=6) _ByteSize/1180696576-12 21.93n ± 1% 21.36n ± 1% -2.60% (p=0.002 n=6) _ByteSize/1099511627776-12 18.41n ± 1% 18.07n ± 1% -1.82% (p=0.002 n=6) _ByteSize/1209033293824-12 21.64n ± 2% 21.03n ± 1% -2.84% (p=0.002 n=6) _ByteSize/1125899906842624-12 18.17n ± 1% 17.77n ± 1% -2.17% (p=0.002 n=6) _ByteSize/1238050092875776-12 21.28n ± 0% 20.79n ± 1% -2.30% (p=0.002 n=6) _ByteSize/1267763295104794624-12 20.97n ± 1% 20.74n ± 2% -1.07% (p=0.035 n=6) _GetMIME/fiber-12 40.44n ± 1% 39.98n ± 1% -1.14% (p=0.004 n=6) _ParseVendorSpecificContentType/vendorContentType-12 26.79n ± 1% 25.99n ± 1% -2.99% (p=0.002 n=6) _ParseUint/fiber_bytes-12 7.171n ± 1% 7.087n ± 2% -1.18% (p=0.026 n=6) _ParseInt/fiber-12 7.095n ± 1% 7.004n ± 1% -1.28% (p=0.015 n=6) _ParseInt/fiber_bytes-12 7.470n ± 1% 7.333n ± 1% -1.83% (p=0.002 n=6) _ParseInt16/fiber_bytes-12 5.183n ± 2% 5.064n ± 3% -2.31% (p=0.045 n=6) _ParseInt8/fiber-12 4.429n ± 1% 4.638n ± 2% +4.72% (p=0.002 n=6) _ParseInt8/fiber_bytes-12 4.417n ± 1% 4.551n ± 1% +3.05% (p=0.002 n=6) _ParseUint32/fiber-12 6.843n ± 0% 6.978n ± 1% +1.97% (p=0.002 n=6) _ParseUint32/fiber_bytes-12 7.128n ± 1% 7.282n ± 1% +2.15% (p=0.004 n=6) _ParseUint16/fiber-12 4.566n ± 1% 4.685n ± 1% +2.61% (p=0.002 n=6) _ParseUint16/fiber_bytes-12 4.704n ± 1% 4.785n ± 1% +1.73% (p=0.009 n=6) _ParseUint8/fiber-12 3.657n ± 1% 3.588n ± 1% -1.87% (p=0.002 n=6)Bug Fixes
Performance Improvements
New Features
Tests
✏️ Tip: You can customize this high-level summary in your review settings.
Summary by CodeRabbit
New Features
Bug Fixes
Tests
Refactor
✏️ Tip: You can customize this high-level summary in your review settings.