Repository navigation
Sort the result cache's package dependencies before writing them - #6370
SanderMuller wants to merge 2 commits into
Conversation
fb89904 to
2252ebd
Compare
|
I am not sure its worth sorting the results or whether a diff/debug-tool should do it before comparing |
|
Good question, and it made me go and check which of the reasons actually survive. One of the three I had in mind does not, so here they are with numbers. Two cold runs of the same 4524-file project, 75.3 MB cache, same size every time. Diffing, which is your point. You are right that a tool could canonicalise first. Worth knowing that plain That is Ondřej's pro-tip from your 2023 post, diffing the cache to find out why it was not reused. It works today, in any shell, without a tool existing. A tool that sorts first would work too, it just has to be written first and then parse every frame and know which sections are order-insensitive. Content hashing, which a tool cannot retrofit cheaply. Without the sort you cannot content-address the file at all. With it, two runs are identical apart from Deduplication, which I had in the description and which does not hold up. I measured what an incremental store or transfer would actually rewrite between two runs, and the ordering churn is localised: So about half a megabyte per run. Not worth carrying code for, and I will drop that claim from the description. Cost of the sort, on the real array from that project (4524 files, 2792 package names): median 0.454 ms as it comes out of the run, 0.861 ms if I shuffle it first as a worst case, against a cold run of about 30 s. So the case is the diff line count and the hashability, not storage. If neither is worth 0.5 ms to you and Ondřej, I am happy to close it, that is a fair reading of the same numbers. Separately, the description said there was no e2e fixture, which is out of date since I pushed one. Updating it now. |
540c2c9 to
8f34270
Compare
8f34270 to
e293141
Compare
e293141 to
bee7b0d
Compare
| // Every other section above is ordered before it is written; this one was not, so its order | ||
| // followed the order the workers happened to finish in. Two identical runs of a 4524-file | ||
| // project produced 74.9 MB caches of the same size differing in 468652 bytes; with this sort | ||
| // they differ in the 2 bytes of lastFullAnalysisTime, which is meant to differ. That costs |
There was a problem hiding this comment.
This comment is verbose and totally unnecessary
There was a problem hiding this comment.
Removed. I also shortened the comments in the e2e fixture.
Every other section of the file is ordered before it is written; this one followed the order the workers happened to finish in, so two identical runs of a 4524-file project produced caches of the same size differing in 9848 lines. A run reading the file back does not care, but it means a result cache cannot be hashed, deduplicated or compared between machines. The packages of a single file need the same treatment: they are collected in the order that file's dependencies are reflected, so a file naming Mailer before Logger records their packages in that order. The e2e fixture makes both observable without depending on a race. Four files are split into two parallel jobs, so the section reaches the main process interleaved and no worker completion order can put it in ascending order by accident; and each file declares the two packages in reverse alphabetical order. Dropping either sort fails the assertion on every run, naming what is out of order. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The check now reads the current entry frames. The fixture files reference Logger before Mailer, because that order records test/mailer first on 2.3.x, so the check still fails without the sort of a file's packages. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
bee7b0d to
72be704
Compare
save()writes thepackageDependenciessection of the result cache without sorting it. The section follows the order in which the workers finish, so two runs of the same project write different files.With the sort, two cold runs of a 4524-file project wrote files that differ only in
lastFullAnalysisTime. Without it they differed in 615894 bytes. The file can then be compared withdiff -aor with a content hash. The sort costs about 0.5 ms per save on that project. I measured these numbers on 2.3.x in September.The packages of one file get a sort too, because they come in the order in which the file's dependencies are found.
e2e/result-cache-deterministic-orderfails without either sort.🤖 Generated with Claude Code