jntemplate 是一款國產的文本決議引擎(模板引擎),最近2.0的版本進行了重構,筆者在Gihub上挑了幾個模板引擎做了一個簡單的小對比測驗,看下國產的質量怎么樣!
環境說明:
作業系統:Windows 10.0.19041.746
CPU: Intel Xeon CPU E3-1231 v3 3.40GHz
記憶體:8G
.NET 框架: net 5
測驗工具:BenchmarkDotNet 0.12.1
參與測驗的引擎:
JinianNet.JNTemplate 2.0.0
Mustachio 2.1.0
RazorEngineCore 2020.10.1
RazorLight 2.0.0-rc.3
Scriban 3.4.2
說明一下,Razor官方是視圖引擎,不方便直接測驗,所以找了二款基于Razor的第三方引擎來參與測驗,其中RazorEngine因為版本太老無法支持.net 5,故選擇了RazorLight 與RazorEngineCore
以 上檔案均從nuget安裝,語法參照官檔案撰寫并盡量統一,
測驗一:輸出一個變數或者屬性
測驗用代碼:
using BenchmarkDotNet.Attributes;
using JinianNet.JNTemplate;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Test
{
[MemoryDiagnoser]
public class TestVariable
{
[Benchmark]
public void RunJntemplate()
{
var template = Engine.CreateTemplate("Hello $model.Id !");
template.Set("model", new UserInfo { Id = 10, Name = "your name!" });
var value = https://www.cnblogs.com/hnvvv/archive/2021/02/05/template.Render();
}
[Benchmark]
public void RunMustachio()
{
var template = Mustachio.Parser.Parse("Hello {{Id}} !");
dynamic model = new System.Dynamic.ExpandoObject();
model.Id = 10;
model.Name = "your name!";
var value = https://www.cnblogs.com/hnvvv/archive/2021/02/05/template(model);
}
[Benchmark]
public void RunScriban()
{
var template = Scriban.Template.Parse("Hello {{Id}} !");
var value = https://www.cnblogs.com/hnvvv/archive/2021/02/05/template.Render(new UserInfo { Id = 10, Name ="your name!" });
}
[Benchmark]
public void RunRazorEngineCore()
{
//RazorEngineCore.IRazorEngineCompiledTemplate template;
var razorEngine = new RazorEngineCore.RazorEngine();
var template = razorEngine.Compile("Hello @Model.Id");
var value = https://www.cnblogs.com/hnvvv/archive/2021/02/05/template.Run(new UserInfo { Id = 10, Name ="your name!" });
}
[Benchmark]
public void RunRazorLight()
{
var engine = new RazorLight.RazorLightEngineBuilder()
// required to have a default RazorLightProject type,
// but not required to create a template from string.
.UseEmbeddedResourcesProject(typeof(UserInfo))
//.SetOperatingAssembly(typeof(UserInfo).Assembly)
.UseMemoryCachingProvider()
.Build();
string template = "Hello @Model.Id";
var model = new UserInfo { Id = 10, Name = "your name!" };
string result = engine.CompileRenderStringAsync("templateKey", template, model).GetAwaiter().GetResult();
}
}
}
測驗結果:

這里可以看到二個razor引擎所需要的時間是最長的,這是因為它們是編譯型引擎,初始運行需要進行編譯,所以會占用較多時間,
不過為什么jntemplate也是編譯型引擎,所占時間卻最少呢?
測驗二:測驗一的代碼一共運行10萬次
即然一次說明不了什么,接下來我們進行第二項測驗,把上面的代碼各運行10萬次,
測驗代碼:
using BenchmarkDotNet.Attributes;
using JinianNet.JNTemplate;
using RazorEngineCore;
using System.Collections.Concurrent;
namespace Test
{
[MemoryDiagnoser]
public class TestVariableMultiple
{
private int Max = 100000;
[Benchmark]
public void RunJntemplate()
{
string text = "Hello $model.Id";
var hashCode = text.GetHashCode().ToString();
for (var i = 0; i < Max; i++)
{
var template = JinianNet.JNTemplate.Engine.CreateTemplate(hashCode, text);
template.Set("model", new UserInfo { Id = 10, Name = "your name!" });
var value = https://www.cnblogs.com/hnvvv/archive/2021/02/05/template.Render();
}
}
[Benchmark]
public void RunScriban()
{
Scriban.Template template = Scriban.Template.Parse("Hello {{Id}} !");
for (var i = 0; i < Max; i++)
{
var value = https://www.cnblogs.com/hnvvv/archive/2021/02/05/template.Render(new UserInfo { Id = 10, Name ="your name!" });
}
}
[Benchmark]
public void RunMustachio()
{
var template = Mustachio.Parser.Parse("Hello {{Id}} !");
for (var i = 0; i < Max; i++)
{
dynamic model = new System.Dynamic.ExpandoObject();
model.Id = 10;
model.Name = "your name!";
var value = https://www.cnblogs.com/hnvvv/archive/2021/02/05/template(model);
}
}
[Benchmark]
public void RunRazorEngineCore()
{
var TemplateCache = new ConcurrentDictionary();
string text ="Hello @Model.Id";
int hashCode = text.GetHashCode();
for (var i = 0; i < Max; i++)
{
IRazorEngineCompiledTemplate compiledTemplate = TemplateCache.GetOrAdd(hashCode, i =>
{
RazorEngine razorEngine = new RazorEngine();
return razorEngine.Compile(text);
});
var value = https://www.cnblogs.com/hnvvv/archive/2021/02/05/compiledTemplate.Run(new UserInfo { Id = 10, Name ="your name!" });
}
}
[Benchmark]
public void RunRazorLight()
{
var engine = new RazorLight.RazorLightEngineBuilder()
.UseEmbeddedResourcesProject(typeof(UserInfo))
.UseMemoryCachingProvider()
.Build();
string template = "Hello @Model.Id";
var model = new UserInfo { Id = 10, Name = "your name!" };
for (var i = 0; i < Max; i++)
{
if (i==0)
{
string result = engine.CompileRenderStringAsync("templateKey", template, model).GetAwaiter().GetResult();
}
else
{
var cacheResult = engine.Handler.Cache.RetrieveTemplate("templateKey");
if (cacheResult.Success)
{
var templatePage = cacheResult.Template.TemplatePageFactory();
string result = engine.RenderTemplateAsync(templatePage, model).GetAwaiter().GetResult();
}
}
}
}
}
}
測驗結果:

運行10萬次后,編譯型引擎的速度明顯占優
測驗三:foreach 遍歷10萬次
測驗代碼:
using BenchmarkDotNet.Attributes;
using JinianNet.JNTemplate;
using RazorEngineCore;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Test
{
/// <summary>
/// /
/// </summary>
[MemoryDiagnoser]
public class TestForeach
{
private int[] arr;
private int max = 100000;
public TestForeach()
{
arr = new int[max];
for(var i = 0; i < max; i++)
{
arr[i] = i;
}
}
[Benchmark]
public void RunScriban()
{
var template = Scriban.Template.Parse(@"
<ul id='products'>
{{ for product in products }}
<li>{{ product }}</li>
{{ end }}
</ul>
");
var result = template.Render(new { Products = arr });
}
[Benchmark]
public void RunJntemplate()
{
string text = @"
<ul>
$for(node in list)
<li>$node</li>
$end
</ul>
";
var hashCode = text.GetHashCode().ToString();
var template = JinianNet.JNTemplate.Engine.CreateTemplate(hashCode, text);
template.Set("list", arr);
var value = https://www.cnblogs.com/hnvvv/archive/2021/02/05/template.Render();
}
[Benchmark]
public void RunRazorEngineCore()
{
var razorEngine = new RazorEngineCore.RazorEngine();
var TemplateCache = new ConcurrentDictionary();
string text = @"
<ul>
@{
foreach (var item in Model)
{
<li>@item</li>
}
}
</ul>
";
var template = razorEngine.Compile(text);
var value = https://www.cnblogs.com/hnvvv/archive/2021/02/05/template.Run(arr);
}
[Benchmark]
public void RunRazorLight()
{
var engine = new RazorLight.RazorLightEngineBuilder()
// required to have a default RazorLightProject type,
// but not required to create a template from string.
.UseEmbeddedResourcesProject(typeof(UserInfo))
//.SetOperatingAssembly(typeof(UserInfo).Assembly)
.UseMemoryCachingProvider()
.Build();
string text = @"
<ul>
@{
foreach (var item in Model)
{
<li>@item</li>
}
}
</ul>
";
string result = engine.CompileRenderStringAsync("templateKey", text, arr).GetAwaiter().GetResult();
}
}
}
測驗結果:

mustachio沒有找到怎么foreach的語法,這里就沒測驗,Scriban 支持不了這么大的陣列,所以沒有結果,
還有一些復雜的用法,今天暫時就不測了,結論我就不用說了,當然本次測驗并不完整,畢竟一個引擎涉及到的地方很多,僅僅一二個用法不能代表不了全部,所以結果僅供參考,
另外mustachio功能上太簡單,其實無法和其它引擎相提并論,這里只拿來只是湊個數!
大家怎么看呢?
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/256996.html
標籤:.NET技术
