This change significantly reduces the amount of string and List<ISymbol>
allocations that occur during compilation by changing the way
LiteralChunks are combined.
This is a low impact fix that addresses the performance issue, the design
issues that caused it still exist.
The problem here lies in what Razor fundamentally does - it parses HTML/C#
into tokens, and then combines them back into 'chunks' a representation
friendly to code generation. When presenting with a large block of static
HTML, Razor parses it into individual HTML tokens, and then tries to join
them in back into a single chunk for rendering. Due to details of Razor's
representation of chunks/tokens, the process of combining literals is too
expensive.
Mainly, what's done here is to not try to combine instances of
LiteralChunk. The process of merging them is too expensive and requires
lots of interm List<ISymbol> and string allocations.
Instead we produce a new 'chunk' ParentLiteralChunk, which doesn't do so
much up-front computing. Various pieces of the code that deal with
LiteralChunk need to be updated to deal with ParentLiteralChunk also,
which is the bulk of the changes here.
Note that we still have the potential for LOH allocations to occur during
codegen, but it's likely to occur O(1) for each large block of HTML
instead of O(N) as it did in the old code.
- Now that what used to be CodeGenerators are now ChunkGenerators we can rename the CodeBuilder into its correct structure: a CodeGenerator.
- Moved the TagHelperAttributeValueCodeRenderer from the TagHelpers namespace into the CodeGeneration namespace.
- Went through several classes and remove and sorted usings.
- Updated test files to abide by the new naming convention of Builders => CodeGenerators.
#140
- Renamed CodeGenerators to ChunkGenerators.
- Updated location of TestFiles from TestFiles/CodeGenerator/CS/{Output|Source} => TestFiles/CodeGenerator/{Output|Source}.
- Removed ChunkTree test; it was a legacy test used to experiment with Razor rendering (not a real test).
- Removed CSharpRazorCodeGenerator; it's now replaced with RazorCodeGenerator. It was an empty class that did nothing.
- Updated ChunkBlock => ParentChunk. Also updated several patterns throughout the code base that referenced these blocks as blocks and not parents.
- Moved Chunks and ChunkGenerators into the Chunks/Chunks.Generators namespace/folder structure. Updated test project to reflect the same.
- Moved CodeBuilders and CodeVisitors to the CodeGeneration/CodeGeneration.Visitors namespace/folder structure. Updated test project to reflect the same.
- Moved several TagHelper assets outside of their own namespaces and into Razors more general structures; such as CodeGeneration and Chunks/Chunks.Generators.
#140