String Concat In Loop
ID |
swift.string_concat_in_loop |
Severity |
low |
Remediation Complexity |
trivial |
Remediation Risk |
low |
Remediation Effort |
low |
Resource |
Efficiency |
Language |
Swift |
Tags |
efficiency, performance |
Description
Reports a += whose right-hand side contains a string literal
(or interpolation literal) inside a loop body. Each iteration
allocates a new String; on long inputs the cumulative cost is
quadratic.
for x in xs {
s += "\(x), " // FLAW
}
let s = xs.map { "\($0)" }.joined(separator: ", ") // OK
Rationale
Swift String is a value type with copy-on-write storage. Each
s += literal reallocates s’s storage to fit the appended bytes;
on `n iterations the total work is O(n²) in characters. Built-in
combinators (joined(separator:), reduce(into:)) write to a
single buffer and run in O(n).
Remediation
Build a collection first and join once, or write into a single
var s allocated to the expected capacity:
let s = xs.map { "\($0)" }.joined(separator: ", ")
// or, when joined doesn't fit the shape:
var s = ""
s.reserveCapacity(xs.count * 4)
for x in xs {
s.append("\(x), ")
}
The rule is conservative: it requires the RHS to contain a string
literal, so it doesn’t flag numeric += or array appends.