Skip to content

Improve flexible ISO8601 validation throughput#168

Open
trevorprater wants to merge 1 commit into
segmentio:masterfrom
trevorprater:codex/iso8601-flexible-fast-path
Open

Improve flexible ISO8601 validation throughput#168
trevorprater wants to merge 1 commit into
segmentio:masterfrom
trevorprater:codex/iso8601-flexible-fast-path

Conversation

@trevorprater

Copy link
Copy Markdown

This adds a fast path for iso8601.Valid when called with Flexible, which is the mode used by the existing BenchmarkValidate benchmark. The fast path keeps the same validation rules but walks the string by index instead of repeatedly slicing through readDigits / readByte.

I kept the existing generic flag path unchanged for non-Flexible combinations.

Validation:

go test -count=1 ./...
ok  	github.com/segmentio/encoding/ascii	0.178s
?   	github.com/segmentio/encoding/internal/runtime_reflect	[no test files]
ok  	github.com/segmentio/encoding/iso8601	3.175s
ok  	github.com/segmentio/encoding/json	0.780s
ok  	github.com/segmentio/encoding/json/bugs/issue11	0.537s
ok  	github.com/segmentio/encoding/json/bugs/issue136	0.876s
ok  	github.com/segmentio/encoding/json/bugs/issue18	0.648s
ok  	github.com/segmentio/encoding/json/bugs/issue84	0.763s
ok  	github.com/segmentio/encoding/proto	0.985s
ok  	github.com/segmentio/encoding/thrift	1.093s

I also ran a temporary differential test comparing Valid against the previous implementation for every flag combination over fixed edge cases and 50,000 deterministic randomized strings.

Benchmark command:

go test -run '^$' -bench '^BenchmarkValidate/(success|failure)$' -benchmem -count=20 ./iso8601

benchstat:

goos: darwin
goarch: arm64
pkg: github.com/segmentio/encoding/iso8601
cpu: Apple M4
                    │ baseline-bench.txt │ final-bench.txt │
                    │       sec/op       │     sec/op      vs base                │
Validate/success-10        13.960n ± 6%       6.205n ± 1%  -55.55% (p=0.000 n=20)
Validate/failure-10        11.570n ± 2%       4.454n ± 1%  -61.50% (p=0.000 n=20)
geomean                    12.71n             5.257n       -58.63%

                    │ baseline-bench.txt │ final-bench.txt │
                    │        B/op        │      B/op       vs base                 │
Validate/success-10        0.000 ± 0%         0.000 ± 0%       ~ (p=1.000 n=20)
Validate/failure-10        0.000 ± 0%         0.000 ± 0%       ~ (p=1.000 n=20)

                    │ baseline-bench.txt │ final-bench.txt │
                    │     allocs/op      │   allocs/op     vs base                 │
Validate/success-10        0.000 ± 0%         0.000 ± 0%       ~ (p=1.000 n=20)
Validate/failure-10        0.000 ± 0%         0.000 ± 0%       ~ (p=1.000 n=20)

I found the initial direction while experimenting with Sleepy - https://sleepy.run/mcp, then manually reduced it to this smaller Flexible-only patch and validated it locally.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant