Equal performance of DecodeRuneInString(s) and rune(s) without rune allocation.
What did you see instead?
rune(s) causes unnecessary allocation of rune slice using runtime.stringtoslicerune (https://go.godbolt.org/z/nb9538EvP). This expression just can be replaced by runtime.decoderune and bounds check.
The text was updated successfully, but these errors were encountered:
I dont think this pattern is common enough to warrant special handling. Generally the unicode packages should be preferred over rune. Otherwise we end up in a state were some rune patterns are optimised and can be used and others arent or dont have equivalent rune expressions.
All the optimisations on strings also create an asymmetry because equivalent byte slice expressions are not optimized.
Specific to this case I think its also not very practical to use rune(s) since it would need a check for an empty string to not cause index failures. Since to me its seems that check can be easily forgotten I think its better to use DecodeRuneInString. rune(s) also doesnt allow to differentiate the case of invalid encoding vs decoding a RuneError rune which is needed for string processing loops which try to decode a sequence of runes from a string.
As rune(s) has some new pitfalls and less utility than DecodeRuneInString I think we should not further encourage its usage by making that pattern faster.
Encouraging rune(s) over DecodeRuneInString also increases the performance differences between Go compilers as other Go compilers would also need to implement the optimisation. It seems better to me to just to keep on using the already fast version of DecodeRuneInString that doesnt need any special pattern but only generic code optimisations.
As a side note: If I will be allowed to remove compiler special handling of len(rune) I would remove it. Which is I think the only special handling of this case.
I did some code search. The number of occurrences of rune(s)[?] is not super high, e.g. a couple hundreds in 5m lines of code, so it may merit a static checker in StaticCheck, but it is not a good candidate as a vet checker because:
It does not occur very often.
It is about performance rather than correctness.
s may be a short string such that the cost of rune(s) is very low. This issue is serious only if s is a very long string.
I agree that the benefits here for adding an optimization or vet check seem to small to justify the added maintenance cost of that code. It should be easy enough for someone to write their own linter for this using x/tools/go/analysis.