Announcing the beta release of Web Pages 3.2.1

The NuGet packages for ASP.NET Web Pages 3.2.1 beta are now live on the NuGet gallery!

Download this release

You can install or update the NuGet package for ASP.NET Web Pages 3.2.1 beta using the NuGet Package Manager Console, with the following commands:

  • Install-Package Microsoft.AspNet.WebPages -Version 3.2.1-Beta –Pre

Prerequisites for this release

What’s in this release?

This release provides a performance improvement in rendering razor pages.

We worked with the MSN team on rendering large pages. When pages render over 80 Kilobytes of data, we end up with objects on the large object heap. When multiple layers of layouts are used this effect can be multiplied.

The result on the server is extra CPU usage, longer retention of memory, and even long pauses during Gen2 cleanup in the garbage collector.

Below is a table demonstrating the results of analyzing a perfview for a run. The CPU is held constant at about 68%, while large pages are being rendered. The table shows that the number of Generation 2 collections has been almost completely eliminated, and the result is higher request rate and a considerable reduction in pauses due to garbage collection.

Area Before (3.2) After (3.2.1) Delta %
Total request (count) 26,986 32,591 20.80%
Trace duration (seconds) 196.20 198.60 1.20%
Request/second 137.53 164.10 19.30%
CPU Load 68.80% 68.50%   -0.40%
GC CPU Samples 124,323 17,543 -85.90%
Total allocations (count) 55,357,146 57,222,949 3.40%
Total GC Pause (samples) 15,091 8,515 -43.60%
Gen0 GC (count) 403 1,216 201.70%
Gen1 GC (count) 290 367 26.60%
Gen2 GC (count) 229 2 -99.10%
CPU / request (samples/req) 19.73 16.47 -16.50%

 

Update:

How was this done? The Razor page took the data built up in a StringBuilder, and called .ToString() in order to write the string to the wire. Similarly this happened when rendering a Razor page inside a Layout page.

It’s common knowledge that you don’t want to build up a string by concatenating multiple strings. But when the result is large enough, you also don’t want to materialize it into a large string because of the reasons above.

Instead we copy the data into a small buffer, and write to the wire (or the layout page) from this buffer, thus avoiding allocating a large object. Further more the total memory consumed is now reduced because we never have to allocate the full string.

Questions and feedback

You can submit questions related to this release on the ASP.NET forums (MVC, Web API, Web Pages).Please submit any issues you encounter and feature suggestions for future releases on our CodePlex site.

Thanks and enjoy!