-
Notifications
You must be signed in to change notification settings - Fork 4.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
String interpolation can be optimized #22594
Comments
Alignment can optimised too, if expression's type is string. $"{HelloWorldString,-20}"
/* can transformed into */
HelloWorldString.PadLeft(20," "c) and $"{HelloWorldString,20}"
/* can transformed into */
HelloWorldString.PadRight(20," "c) |
@AdamSpeight2008 I know, but that will significantly increase the size of the generated code. Also, in my experience, this happens far less frequently in real world code. More importantly, I think that is a different case. I wanted to tackle this case first. Alignment can be handled later if deemed useful. |
This sounds like a variation of all the other (closed) issues, like #9212 (see the web of linked issues as well) |
@khellang It is a variation on #9212, but the approach taken is fundamentally different. #9212 was about replacing the lowering to |
So #6669? Hence why I said "see the web of linked issues as well" 😉 |
The key difference between this suggestion and similar suggestions in the past (including #6669), is that this modifies only the case where all fill-ins are strings. Those do not have the complexity of culture-sensitive formatting. |
My only real concern with such an optimization is that it encodes assumptions regarding the implementation of Beyond that I think it's a good idea, though. Or would this also fall under the post-compilation optimization step that has been suggested for inlining LINQ queries? |
To be precise, the way I implemented my PR, it encodes the assumption that The assumption that More broadly speaking, every constant folding optimization depends on the assumption that a calculation done at compile time is equivalent to doing the same (or an equivalent) calculation at runtime. That also applies to the assumption that
If any of the above assumptions are broken, it would be a massive breaking change, impacting virtually all programs running on .NET. That is very unlikely to happen, to say the least. And when it does, the compiler is in trouble anyway.
I agree :-)
No. The way I implemented this in #22595 is in the lowering of interpolated strings, similarly to how the optimizations of string concatenation are implemented. |
I took a deep dive into the question whether this optimization is correct a couple of years ago. It looks to me like the specification for string formatting allows for the possibility of a custom culture that provides its own custom formatting for a string value when used as an interpolation. Based on that I concluded that it would not be correct to do this optimization. See #9212 (comment) However. I tried constructing such a custom culture and found that the implementation never would call it for a value of type string. Technically, this is a bug in the implementation of string formatting, but it is probably something that will never change. If anything, I would expect the spec (or my understanding of it) to be changed. Therefore the optimization is probably OK. This was previously considered and rejected in #9212, #6669, #4678, #194, and #76. But now @KrisVandermotten has used up his accumulated Karma and forced us to reconsider. Karma reset to zero. 😉 |
Might that open the door to potentially using interpolation for string constants as long as the arguments are also string constants? |
@HaloFour Seems plausible but possibly complex (the formatting would have to be specified in the language spec, and the constant is still convertible to FormattableString with the fill-ins separately preserved). I suggest opening a new issue for it. I'm not sure what would motivate us to want to do that (over other things we could do with our time). |
There are a couple of issues on this repo too although they seem to focus on the performance aspect rather than possibly opening up interpolation up to other scenarios, such as use with attributes. Granted, interpolation in this limited form isn't appreciably different from just using |
I wish you could throw these "nice to have" features to X.X milestone to get feedback and prioritize, at least it shows that the proposal is accepted in principle. It seems like the discussions are more constructive and helpful if the issue has the word "champion" in the title. The fact that there's an official thread for a potential language feature helps to keep the discussion in one place instead of multiple issues scattered all over the repo. |
Indeed. The way I understand it is that the
That is what makes this optimization safe. And honestly, I cannot imagine this to ever change. Furthermore, as I said before, an optimization with a similar assumption already exists in string concatenation today: the assumption that See LocalRewriter_StringConcat.cs line 370:
A similar reasoning applies: for both |
Perhaps if we can get the Core people to guarantee that (maybe with a doc change), then this would be more palatable? It seems like something they'd be willing to say and doc. |
Not sure what kind of guarantee you're looking for. The behavior is documented:
|
I would consider that a good guarantee :) |
@KrisVandermotten Should this issue remain open for further optimizations? Or can it be closed (fixed by #26612)? |
@jcouv Further optimizations are certainly not impossible, but what was described here has been done. New work, if any, can be done through new issues and/or pull requests. |
Thanks again. |
String interpolation has proven to be a very successful feature. Some people even replace efficient concatenation by interpolation, assuming the new syntax is just as efficient. However, that is not the case.
The LDM of May 21, 2014 noted:
So far, nothing has been done to optimize interpolated strings in this way.
I believe there are five scenarios:
IFormattable
).Case 2 is surprisingly common. Last time I counted, Roslyn.sln had 1355 cases. It is also the easiest one to optimize. Basically, the call to
string.Format
can be replaced with string concatenation. That string concatenation is itself then lowered, often to a call tostring.Concat
. That lowering will perform constant folding, so in some cases no call is needed at all. Performance differences can be significant.I have prepared pull request #22595 to handle this case.
The text was updated successfully, but these errors were encountered: