fs: make the Into<Path> conversion of std/fs cheaper, lower 19 allocation budgets (step 2d of #68) #728
Labels
No labels
loop
queue/failed
queue/queued
ready
status/parked
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
torbscript/language#728
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Context
Step 2d of the epic #68 (PATH.md slice 2). Since
std/fstakesInto<Path>(#547, landed 2026-10-28) every call builds aPathfirst:Stringis parsed into a root plus a component list, and the wrapper then renders it again withshow()(textOfinstd/fs/src/lib.trb), or the native takes theInto<Path>parameter and converts it once. Programs that callstd/fstherefore allocate more blocks. The regression was found by tier B onmain(issue #550) and the 19.allocationsbudgets were raised in PR #556 ("making theInto<Path>conversion cheaper ... would lower the budgets again" was named there as not done). This issue does that.Source
From<String>is infallible), section 5 (Into<Path>as a parameter type), section 6 (the boundary to the operating system,systemPath); slice 2 in section 8.compiler/CONTRIBUTING.md(tier B holds.allocationsexactly on linux x86_64; a count below the budget passes and names it; lower withsh tools/conformance.sh --update-budgets --filter <program>; "Measure astd/body with a compiled probe"),docs/PERFORMANCE.mdsection 6.std/pull requests).The numbers (budget before step 2 -> raised in PR #556 -> on
maintoday)The "today" column is the file on
mainat the time of filing (it moved after #556 through other changes); the target below is stated against "before", the measured count is what tier B prints.Design (decided by the loop, internal)
File.readText("a/b")go (parse of theString, the component list and its strings,show()of the result, the copy for the native)? Record the per-call count in the PR.Stringor literal argument whose text is already the/form (the common case) so theStringgoes to the runtime without building aPath; (2) one conversion at the entry of a wrapper instead of one per helper (textOfonce, the helpers take theString); (3) a cheaperPath.from(fewer intermediate strings and lists). Semantics stay exactly those of PATH.md:\separates, the./../empty rules,IoError.pathandlist/absolutePathreturn types unchanged (steps 3 and 4).Pathargument cost more than today is not taken.Acceptance criteria
tests/or described with its counts in the PR body) shows the blocks per call of the conversion before and after.absolute-path-form,file-atomic-replace,files,file-values,long-paths,non-ascii-paths,resource-missingandnative-into-pathare back at or within 25 percent of their "before" value in the table (for exampleabsolute-path-format most 38,file-atomic-replaceat most 408); where a program cannot get there, the PR body names the measured floor and why, and the budget is lowered to that count.sh tools/conformance.sh --update-budgets --filter <program>, never raised..allocationsbudget rises; tier B is green. The numbers are read from forge CI only (tier B on linux x86_64), never from a local run.std/fssemantics are unchanged: thestd/fsandstd/pathtests and the conformance programsnative-into-path,non-ascii-paths,long-pathspass without edits to their expected output.Seed
Does not touch the seed on its own: no syntax, no new native, no driver flag, no name the compiler looks up. If the chosen design needs a lowering change in
compiler/src(design 1 may), it must work with the published seed, otherwise stop and comment here; a seed-touching variant becomes the two-commit rule and a separate issue.Size
One PR, one or two Conventional Commits:
perf(fs): convert Into<Path> arguments without a second Pathandtest(conformance): lower the allocation budgets of the programs that call std/fs(budget lowering as a commit of its own, with the reason in the message).CI note
A pull request that touches only
std/andtests/does not run tier B (tier-bscope inci.yml, see #709), and the budgets are exact. The worker checks the scope; if the PR run has no tier B, the counts come from the tier B of themainrun after landing and any difference is fixed forward in the next commit, as CONTRIBUTING says. Do not guess the counts.Dependencies
None open. Independent of #680 (step 3); both touch
std/fs, so the later one rebases.Part of #68 (the PR says
Refs #68, notCloses).[loop:torbscript] decided by the loop: performance work with a measurable goal, so the loop decides (contract: performance, measurable); no owner question. Reasoning: (1) the regression is exact and known (19 budgets, table in the body, PR #556 raised them and named this follow-up); (2) the acceptance criteria are counts printed by tier B, with a probe first, so the worker measures before choosing among the three designs; (3) no seed impact as filed, a seed-touching variant stops and splits; (4) size one PR, one or two commits. Duplicate search of open and closed issues (Into, allocation budget, conversion cheaper, Path conversion, std/fs): none; #566 (ArrayList over Buffer allocations) is unrelated, #709 (tier B for std/ pull requests) is a neighbour and is noted in the issue. Labels: loop, ready.
Into<Path>signatures (PATH slice 2) #68Into<Path>signatures (PATH slice 2) #68[loop:torbscript] claim implement by session:loop-torbscript-20261113 until 2026-11-13T07:00:00Z
Into<Path>signatures (PATH slice 2) #68[loop:torbscript] release implement: worker timed out after 6 h with no report; PR #729 exists (head
2850b61e), CI pending. next: waiting (PR #729 CI), fix round on the same branch if it goes redInto<Path>signatures (PATH slice 2) #68