Skip to content

perf(json): avoid redundant document decoding and package encoding - #299

Open
ajayk wants to merge 1 commit into
spdx:mainfrom
ajayk:perf/json-roundtrips
Open

ajayk wants to merge 1 commit into
spdx:mainfrom
ajayk:perf/json-roundtrips

Conversation

@ajayk

@ajayk ajayk commented Sep 6, 2026

Copy link
Copy Markdown

JSON reading currently builds a generic object tree for the entire document to inspect spdxVersion, then decodes it again into the versioned model. SPDX 2.2 package serialization also encodes, decodes, and re-encodes each package when its verification code is absent.

Keep top-level JSON fields as json.RawMessage during version detection and omit empty verification codes through a shadowing pointer field. This removes the temporary object tree and the serialization round trip. Public APIs and JSON values remain unchanged; serialized object key order can change.

Adds repeatable benchmarks and regression coverage for supported versions, version errors, malformed input, reader errors, verification-code omission, nested fields, HTML escaping, and marshal errors.

Local benchmark medians over five runs on Apple M5 Pro, darwin/arm64, Go 1.27.1:

Benchmark Time before → after Allocations before → after Bytes before → after
Read, 10 packages 38.4 → 33.0 µs 313 → 95 36,035 → 33,508
Read, 1,000 packages 3.48 → 2.96 ms 27,226 → 6,095 2,819,761 → 2,588,492
Marshal SPDX 2.2 package, verification code absent 3.96 → 1.18 µs 67 → 12 5,140 → 2,291

The verification-code-present control retains the same allocations and bytes, with approximately unchanged timing in longer repeat runs.

Validation: make test passes, including both existing 100,000-input fuzz runs. Regression tests also pass against the original implementation.

Reproduce benchmarks:

go test ./json -run '^$' -bench 'Benchmark(Read|MarshalPackageV22)$' -benchmem -benchtime=300ms -count=5

@kzantow

kzantow commented Sep 30, 2026

Copy link
Copy Markdown
Collaborator

It looks like this PR will need to be rebased -- the JSON reader has had some updates.

Signed-off-by: ajayk <ajaykemparaj@gmail.com>
@ajayk
ajayk force-pushed the perf/json-roundtrips branch from 501d8f7 to 89e926a Compare October 1, 2026 02:30
@ajayk

ajayk commented Oct 1, 2026

Copy link
Copy Markdown
Author

@kzantow can you please review

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.

2 participants