Skip to content

Optimize decoding CBOR byte string - #811

Merged
fxamacker merged 4 commits into
masterfrom
fxamacker/cache-interface-type
Aug 27, 2026
Merged

Optimize decoding CBOR byte string#811
fxamacker merged 4 commits into
masterfrom
fxamacker/cache-interface-type

Conversation

@fxamacker

Copy link
Copy Markdown
Owner

On a new benchmark decoding CBOR byte string to user-defined type with methods, this PR reduces decoding duration by up to 60%. 🚀 On existing benchmarks, this PR reduces decoding duration for CBOR byte string by up to 28% (depending on the data structure and values being decoded).

This PR optimizes decoding of CBOR byte string by:

  • moving the BinaryUnmarshaler and TextUnmarshaler interface checks off the hot path
  • skipping no-op applyByteStringTextConversion for default decoding options
  • caching the byte slice element type check

Benchmarks

Benchmark results for Unmarshal() omit allocs/op and B/op because they are unchanged:

goos: linux
goarch: amd64
pkg: github.com/fxamacker/cbor/v2

NOTE: These benchmark results were produced on a PC running other processes.
Please measure on your own hardware with appropriate settings and workloads.

                                                           │     old      │                 new                 │
                                                           │    sec/op    │   sec/op     vs base                │
Unmarshal/CBOR_byte_string_to_Go_interface_{}                100.05n ± 1%   90.37n ± 1%   -9.68% (p=0.000 n=10)
Unmarshal/CBOR_byte_string_to_Go_[]uint8                      87.85n ± 0%   63.07n ± 1%  -28.21% (p=0.000 n=10)
Unmarshal/CBOR_byte_string_to_Go_cbor.address                158.05n ± 0%   63.38n ± 1%  -59.90% (p=0.000 n=10)
Unmarshal/CBOR_indefinite-length_byte_string_to_Go_[]uint8    309.0n ± 0%   289.1n ± 0%   -6.44% (p=0.000 n=10)
UnmarshalCOSE/128-Bit_Symmetric_Key                           229.2n ± 1%   210.4n ± 0%   -8.20% (p=0.000 n=10)
UnmarshalCOSE/256-Bit_Symmetric_Key                           239.6n ± 0%   218.1n ± 1%   -8.95% (p=0.000 n=10)
UnmarshalCOSE/ECDSA_P256_256-Bit_Key                          416.6n ± 0%   375.5n ± 0%   -9.85% (p=0.000 n=10)
UnmarshalCWTClaims                                            319.8n ± 0%   301.5n ± 0%   -5.72% (p=0.000 n=10)
UnmarshalWebAuthn                                             397.6n ± 0%   377.1n ± 0%   -5.17% (p=0.000 n=10)
UnmarshalCOSEMAC                                              356.2n ± 0%   263.4n ± 1%  -26.05% (p=0.000 n=10)
UnmarshalCOSEMACWithTag                                       407.8n ± 0%   315.4n ± 0%  -22.66% (p=0.000 n=10)

This commit caches type checks to optimize decoding of CBOR byte string
and CBOR text string.

Previously, when decoding a CBOR byte string, fillByteString() checked
if the destination type implements:
- BinaryUnmarshaler, for default options
- TextUnmarshaler, for non-default options

Also, when decoding a CBOR text string, fillTextString() checked if
the destination type implements TextUnmarshaler for a non-default
option.

This commit caches both checks in typeInfo, so the checks are done
once per type.
@fxamacker fxamacker self-assigned this Aug 26, 2026

@x448 x448 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚀

Comment thread cache.go
@fxamacker
fxamacker merged commit dd0d84a into master Aug 27, 2026
16 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants