Correct performance knowledge guidance (#94)

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 667c64a8-eb36-4440-bc41-6a97d8fb5542

Co-authored-by: Jesper Schulz-Wedde <jesper.schulzwedde@microsoft.com>
This commit is contained in:
Jesper Schulz-Wedde 2026-07-14 11:26:29 +02:00 committed by GitHub
parent 5706959e4a
commit 0e06485027
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
31 changed files with 279 additions and 261 deletions

View file

@ -7,16 +7,16 @@ countries: [w1]
application-area: [all]
---
# Use TextBuilder for many string concatenations, especially inside loops
# Use AL TextBuilder for repeated text mutation
## Description
AL `Text` is immutable: each `Result += Piece;` allocates a new buffer and copies the previous content into it. Inside a loop the work is quadratic in the number of pieces. `TextBuilder` is the AL primitive designed for the pattern — per the upstream guidance, "Use `TextBuilder` when concatenating many strings together (for example inside loops)." Its `Append` mutates a growable internal buffer; `ToText()` materializes the final string once at the end.
AL `TextBuilder` is a reference type intended for modifying text without creating a new `Text` value for each change. Microsoft documents it as the performance-oriented AL primitive for concatenating many strings, including loop-built output. `Append` and `AppendLine` build the value, and `ToText` returns the completed text.
## Best Practice
When a procedure assembles a string from many fragments — joining row data into a CSV, accumulating a log buffer, formatting a multi-line message inside a loop — declare a `TextBuilder` local, call `Append` per fragment, and call `ToText()` after the loop. For a fixed number of small fragments, `StrSubstNo` remains the right tool; the rule targets the loop case.
When a loop repeatedly appends fragments to one result, use a `TextBuilder` local and convert once after the loop. Keep ordinary `Text` expressions for a fixed, small number of fragments; this rule is about repeated mutation, not every concatenation.
## Anti Pattern
`if Customer.FindSet() then repeat Csv += Customer."No." + ',' + Customer.Name + '\n'; until Customer.Next() = 0;` — every iteration reallocates and copies the entire string built so far. On a few hundred customers the cost is invisible; on the production-scale table list (`production-scale-tables-warrant-extra-analysis.md`) it dominates the loop.
Building an unbounded export or message with `Result += Fragment` on every iteration when AL's `TextBuilder` directly represents the operation.