fsharp icon indicating copy to clipboard operation
fsharp copied to clipboard

Optimization for string interpolation - simple scenarios: unfolding constants and lowering to concatenation

Open abonie opened this issue 2 years ago • 4 comments

Seems like there is a lot we could do to improve perf of string interpolation. One good example is https://github.com/fsharp/fslang-suggestions/issues/1108, but also some low hanging fruits to start with could be unfolding compile time constants, e.g.:

[<Literal>]
let x = "hello"

[<Literal>]
let y = "world"

let z = $"{x} {y}!"

in the above, the last line could be lowered to let z = "hello world!"

Another one could be lowering to System.String.Concat when it applies, e.g. let f (x: string) (y: string) = $"{x},{y}." could be rewritten as let f (x: string) (y: string) = System.String.Concat(x, ",", y, "."), because we know that all expression holes are filled with objects of type string and there are at most 4 pieces to concatenate.

abonie avatar Nov 09 '23 18:11 abonie

For the second one, here is difference in allocations from calling the first version of the function vs. the second one 1k times in a loop. Using concat: image vs. string interpolation: image

abonie avatar Nov 09 '23 18:11 abonie

I would simplify this to: implement string interpolation as String.Concat in all scenarios. With no helper method around {x} unless one is known to be required. Dealing with constants and other special cases can be treated as a subsequent optimization step.

charlesroddie avatar Dec 03 '23 00:12 charlesroddie

@abonie I see that the PR only works when the inner expressions are strings only. That is not the majority case. Will the PR make it easier to make all expressions concats (i.e. is it a step towards using a collector for all interpolation https://github.com/fsharp/fslang-suggestions/issues/1108) or will it make this harder by adding an exception that needs to be maintained in the future?

charlesroddie avatar Feb 22 '24 22:02 charlesroddie

the PR only works when the inner expressions are strings only. That is not the majority case.

That is true. This issue is specifically about lowering to System.String.Concat and it doesn't really make sense for other cases (when inner exprs are not strings).

Will the PR make it easier to make all expressions concats (i.e. is it a step towards using a collector for all interpolation https://github.com/fsharp/fslang-suggestions/issues/1108) or will it make this harder by adding an exception that needs to be maintained in the future?

I think neither - as far as I can tell, this is largely orthogonal to interpolated string handlers, doesn't make it particularly easier or more difficult to implement them and also won't be superseded by them, since for cases where this optimization applies, it should still be faster than using a collector.

Reopened the issue, because it also mentions unfolding constants, which the PR does not cover. However, will have to estimate how much of a difference that would make vs work needed. Would be nice to tackle interpolated string handlers soon.

abonie avatar Feb 23 '24 11:02 abonie