Skip to content

RazorEngine.NetFramework 5.0.1

Latest

Choose a tag to compare

@github-actions github-actions released this 31 Oct 23:42
· 5 commits to master since this release
2dec217
  • (FIX) A template is compiled only once when several threads miss the cache for it at the same time (RunCompile, and layouts and @Include while a template runs). Before, every thread compiled it: in a test, 8 threads starting together compiled the same template 8 times. Each of these compiles cost the full compile time and loaded another assembly that stays in memory until its AppDomain is unloaded, typically when a web application starts and many requests need the same templates. The other threads now wait for the first compile and use its result, or get its exception if it fails (the next call then compiles again); different templates and different model types still compile in parallel. See Caching.
  • (FIX) new DefaultCachingProvider(), the caching provider of every new TemplateServiceConfiguration, created a second internal cache that was never disposed. Its AppDomain.AssemblyResolve handler stayed registered and kept its objects alive for the life of the process, one per configuration, also after disposing the service.
  • (PERFORMANCE) The default reference resolver (UseCurrentAssembliesReferenceResolver) checks each loaded assembly once instead of on every compile. Checking whether an assembly's file exists took about 60 µs per assembly; with 223 loaded assemblies that was about 16 ms per compile and is now below 0.1 ms after the first compile. The references passed to the compiler are the same.
  • (PERFORMANCE) Anonymous models with lists of anonymous objects (for example new { Items = list.Select(x => new { x.Name, x.Price }) }) render about 4 times faster. For each list item, the dynamic wrapper of such models first tried the DLR, which cannot bind the enumerator of a list of anonymous types, and only then fell back to reflection: three caught exceptions per item. It now remembers, per type, which members without arguments only work with reflection and calls them directly. In a benchmark with 1000 rows, a run took about 4.5 ms instead of 22 ms, with no exceptions instead of about 3000. The results are the same; missing members still fail as before, and members of dynamic objects such as ExpandoObject (which depend on the instance) are resolved as before.
  • (FIX) A null argument in a call on an anonymous model (for example @Model.Formatter.Describe(null)) is passed on. Before, the dynamic wrapper failed with a NullReferenceException before it bound the call.
  • (BUILD) Package validation compares both packages with 5.0.0 (also the Roslyn package now), so the 5.0.x releases are checked to be compatible with 5.0.0. The 5.0.0 entries in CompatibilitySuppressions.xml are removed with it.

NuGet: https://www.nuget.org/packages/RazorEngine.NetFramework/5.0.1
NuGet (Roslyn): https://www.nuget.org/packages/RazorEngine.NetFramework.Roslyn/5.0.1