Skip to content

rediff: speed up Optimize on real-world patches - #22

Open
leafo wants to merge 1 commit into
masterfrom
rediff-perf
Open

rediff: speed up Optimize on real-world patches#22
leafo wants to merge 1 commit into
masterfrom
rediff-perf

Conversation

@leafo

@leafo leafo commented May 18, 2026

Copy link
Copy Markdown
Member

Summary

Three independent, low-risk changes that together cut rediff wall-time materially on production patches while keeping output size within 1% of the existing baseline:

  • bsdiff — vectorize the writeMessages subtract loop. The per-byte bytes.Buffer.WriteByte loop that built each Add payload is replaced with a reusable []byte (DiffContext.addBuf) populated by a new 8-wide unrolled subtractInto helper. Output is byte-identical to the previous implementation.
  • rediff — cache the decompressed patch body across analyzePatch and Optimize. analyzePatch already runs a full brotli decode over the patch body; Optimize previously re-decompressed the same bytes from scratch. The decompressed body is now held on the rediff context and re-read via seeksource.FromBytes, eliminating the second decode pass. Costs ~1.5–2× the compressed patch size in memory between analyze and Optimize; released at the end of Optimize.
  • rediff — lower default brotli quality 9 → 7 in defaultRediffCompressionSettings. On already-bsdiff'd Control streams q=7 encodes ~1.8× faster than q=9 with <1% size growth. q=6 was measured too and produced +1.75% on a real 275MB patch, exceeding the size budget. The field stays configurable via Params.Compression.

Measurements

Against unmodified master, on two real itch.io builds:

patch shape before after speedup size delta
34 MB multifile 861 ms 459 ms 1.876× +0.046%
275 MB multifile 200.5 s 174.2 s 1.151× +0.655%

Test plan

  • go test ./... passes (full suite)
  • go test ./bsdiff/... ./pwr/rediff/... passes
  • subtract change verified byte-identical to the old WriteByte path
  • reviewer: spot-check a large production patch applies + validates after rediff

🤖 Generated with Claude Code

Three independent changes that together cut rediff wall-time materially
on production patches while keeping the output size within 1% of the
existing baseline:

* bsdiff: vectorize writeMessages subtract loop. The per-byte
  bytes.Buffer.WriteByte loop that built each Add payload is replaced
  with a reusable []byte (DiffContext.addBuf) populated by a new
  8-wide unrolled subtractInto helper. amd64 backend can keep the
  pipeline full and drop per-iteration bounds checks. Output is
  byte-identical to the previous implementation.

* rediff: cache the decompressed patch body across analyzePatch and
  Optimize. analyzePatch already runs the full brotli decode pass over
  the patch body; previously Optimize re-decompressed the same bytes
  from scratch. The decompressed body is now held in a buffer on the
  rediff context and re-read via seeksource.FromBytes; the second
  decode pass is gone. Memory cost: ~1.5–2× the compressed patch size
  held between analyze and Optimize, released at the end of Optimize.

* rediff: drop default brotli quality from 9 to 7 in
  defaultRediffCompressionSettings. On bsdiff'd Control streams q=7 is
  ~1.8× faster to encode than q=9 with <1% size growth. q=6 was also
  measured and produced +1.75% size on a real 275MB patch, exceeding
  the size budget — q=7 is the sweet spot. The field stays configurable
  via Params.Compression for callers that want to override.

Measured against unmodified master on two real itch.io builds:
  34MB-patch (multifile):   861ms → 459ms (1.876×, +0.046% size)
  275MB-patch (multifile):  200.5s → 174.2s (1.151×, +0.655% size)

All existing tests pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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