该应用程序需要 JS 支持(程序是用 C# 编写的)并且 JINT 被用作解释器。我注意到当应用程序作为 64 位应用程序运行时性能会显着降低。
我已将其简化为以下示例,该示例说明了该问题:
Stopwatch sw = new Stopwatch();
sw.Start();
for (int i = 0; i < 1000; i++)
{
var engine = new Jint.Engine(cfg =>
{
cfg.Strict(true); // Good practive for javascript
cfg.AllowClr(); // Access to .net
cfg.LimitRecursion(16); // Help stop broken scripts taking down application
cfg.CatchClrExceptions(ex => ex is Exception);
});
try
{
engine.Execute(@"
function test()
{
throw 'Error';
};
test();
");
}
catch (Exception) { }
}
sw.Stop();
Debug.WriteLine(sw.Elapsed);
当它被编译为 32 位应用程序时,大约需要 11 秒。当它被编译为 64 位应用程序时,大约需要 35 秒。请在实际应用程序中经常抛出异常。
有谁知道为什么会这样?
请注意,这只是在调试器下运行时出现的问题。在调试器之外,性能似乎相似。
更新#1
我一直在研究这个,现在有这个例子:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
Stopwatch sw = new Stopwatch();
sw.Start();
for (int i = 0; i < 20000; i++)
{
DefinedDotNetApi();
}
sw.Stop();
MessageBox.Show(sw.Elapsed.ToString());
}
public static void DefinedDotNetApi()
{
var engine = new Jint.Engine();
engine.SetValue("demoJSApi", new DemoJavascriptApi());
var result = engine.Execute("demoJSApi.helloWorldFromDotNet('TestTest');demoJSApi.helloWorldFromDotNet('TestTest')").GetCompletionValue();
}
public class DemoJavascriptApi
{
public string helloWorldFromDotNet(string name)
{
return $"Hello {name} - this is executed in {typeof(Program).FullName}";
}
}
}
运行 32 位应用程序时,这比构建为 64 位应用程序时快 20-30%。
即使这样做:
public static void DefinedDotNetApi()
{
var engine = new Jint.Engine();
engine.SetValue("demoJSApi", new DemoJavascriptApi());
// var result = engine.Execute("demoJSApi.helloWorldFromDotNet('TestTest');demoJSApi.helloWorldFromDotNet('TestTest')").GetCompletionValue();
var result = engine.Execute("function test() { return 'test'; };test();").GetCompletionValue();
}
因此,如果没有 .NET 回调,它在 64 位模式下仍然慢 10-20%。
有人知道为什么吗?
更新#2
此示例显示了 32 位和 64 位进程之间的速度差异。我使用 benchmarkdotnet.org 来显示差异。
public class Program
{
static void Main(string[] args)
{
var summary = BenchmarkRunner.Run<JintTest>();
}
}
[LegacyJitX86Job, LegacyJitX64Job]
[MinColumn, MaxColumn, MeanColumn, MedianColumn]
public class JintTest
{
public JintTest()
{
Test();
}
private const string ContextString = @"/*var test1;var LineupScheduleItem1 = undefined;var LineupScheduleItem2 = undefined;var LineupScheduleItem3 = undefined;var LineupScheduleItem4 = undefined;*/";
[Benchmark]
public void Test()
{
Jint.Engine engine = new Jint.Engine(cfg =>
{
cfg.Strict(true); // Good practive for javascript
cfg.AllowClr(); // Access to .net
cfg.LimitRecursion(16); // Help stop broken scripts taking down application
cfg.CatchClrExceptions(ex => ex is Exception);
});
JavaScriptParser parser = new Jint.Parser.JavaScriptParser(true);
int maxIterations = 500;
for (int i = 0; i < maxIterations; i++)
{
engine.Execute(parser.Parse(ContextString));
}
}
}
该脚本已全部注释掉,并且正在执行中。64 位进程大约慢 30%。脚本是否被解析似乎没有什么区别。
有谁知道为什么会这样?