Improve LargeEncodedText performance - #569
Conversation
|
Don't forget to run the API change by the compatibility council. |
|
I don't think we need any new public surface nor change the current. |
…d virtual method.
SourceText now includes the logic to decode efficiently from streams, throwing if binary files are detected and using LargeEncodedText to avoid the large object heap. EncodedStringText, a shell of its former self, provides the 'desktop' entry point to detect FileStream and decode MemoryStream as byte arrays.
|
Allow me to explain the public API changes. They're all in SourceText.
You might argue that 2 and 3 could have been done with internal methods. However, the wrinkle is that EncodedStringText (the Desktop entry point that contains optimizations for FileStream and MemoryStream, has the "throwIfBinaryDetected" behavior and uses Encoding.Default as the fallback instead of Utf8) is also used in the Workspaces.Desktop layer (there's a linked file reference). It therefore can't use any compiler internal APIs). |
|
@AnthonyDGreen For the attention of the compat council. Please let me know how you'd like me to proceed. |
…ests to use the byte array version.
Use new property syntax in a few places. Removed unused usings.
|
My comment re the parameter throwIfBinary is lost somewhere in the commits. Why couldn't the caller do the check for binary content after SourceText.From returns the SourceText instance? |
|
@tmat Re:"throwIfBinary". It's for the LargeEncodedText case. The 'throwIsBinary' implementation works on the chunks as they are being decoded. It would be inefficient to do the binary check after the fact because LargeEncodedText's indexer is slow. |
|
👍 |
|
@AnthonyDGreen I'm still waiting for a comment from the compat council. Please take a look at the public API changes and let me know what you think. |
|
@pharring I still don't like the flag and throwing an exception. It would be better if we added a method IsBinary() on SourceText |
|
@pharring, is this a complete and accurate description of the compat impact of the change? Source
Have I overlooked anything that you're aware of? |
|
@AnthonyDGreen Yes, that's complete and accurate. |
|
@tmat I tried to explain that already. SourceText.IsBinary() would have to be public and virtual. |
|
@pharring I see. OK. (Public IsBinary would be better imo, but I didn't realize we throw before we decode the entire stream, in that case sounds good). |
|
+1. I think this is a simple enough change with low risk. Go for it. |
Improve LargeEncodedText performance. Includes the following public API changes: Source 1. Source that extends SourceText and attempts to override the Lines property will now fail to compile. 2. Source that called SourceText.From(Stream) will continue to compile but will silently call a new overload with a default value which preserves the current behavior. Binaries 1. Binaries that extended SourceText and override the Lines property will now fail at runtime when running against the next version of Microsoft.CodeAnalysis.dll 2. Binaries that call SourceText.From(Stream) will fail at runtime with MissingMethodException when running against the next version of Microsoft.CodeAnalysis.dll
Automatically detect generated code configuration
Issue #516 talks about a performance problem with LargeEncodedText.
I fixed that, but along the way I had to reconcile the duplication of code between SourceText, EncodedStringText and LargeEncodedText.
LargeEncodedText is entirely portable, so it was easily moved into the Portable compiler assembly.
Most of EncodedStringText is portable. The class itself is just a re-implementation of StringText. The non-portable stuff remains: Using Encoding.Default as a fallback, throwing if a binary file is detected and special-casing FileStream and MemoryStream.