You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
perf: an archive names its directories once and encrypts into one buffer
Two findings from the performance report, both in internal/format/archive
and neither moving a byte.
P9: Layout.Path rebuilt the directory chain for every entry, through a
fmt format verb, though the chain depends only on the depth. Prefix()
builds it and the two hot callers hoist it out of their loops. Measured
at depth 50 over 10 000 entries: 82.2 ms before, 30.6 ms once the verb
went, and close to nothing with the prefix built once. The default depth
is zero, where the prefix is empty and none of this was ever paid - so
this is the ceiling of a setting rather than a run anybody has.
P10: the two locked-entry writers allocated a fresh buffer on every
Write. At 128 MB in 32 kB blocks that is about four thousand allocations.
The buffer now lives as long as the entry. It cannot be done in place:
p belongs to the caller and the zip writer passes the same slice on, so
scrambling it would corrupt what somebody else is about to read. That is
written next to both writers.
The report never measured P10 - entryWriter is unexported - and the clock
does not settle it either, since the processor time ranges overlap. The
collector count does, and it is deterministic: a 128 MB locked zip went
from 48 collections to 6 with aes-256 and 7 with zipcrypto.
No new guard, deliberately. Path length against LongestPath and the
locked archive's exact size were both already guarded, and adding a
fourth defence beside three is the shape this project has thrown away
seven times. Three mutations prove those guards catch the broken version.
One mutation pattern went stale in the same step, quoting the call this
change rewrote, and staleness.py caught it.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
0 commit comments