アプリケーションは 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% 遅くなります。スクリプトが解析されているかどうかに違いはないようです。
なぜこれが当てはまるのか誰にも分かりますか?