Hi people, I'm using ClearScript for some JavaScript integration recently, and noticed that calling a V8 function is exceptionally expensive if the calling method is being invoked for the first time, creating high latency. To demonstrate the problem I created this:
Thanks!
class Program
{
static V8ScriptEngine engine;
static void Main(string[] args)
{
engine = new V8ScriptEngine(V8ScriptEngineFlags.DisableGlobalMembers);
dynamic func = engine.Evaluate("(function(){})");
Console.WriteLine("3 times per call (1st)");
CallMultipleTimes(func);
Console.WriteLine();
Console.WriteLine("3 times per call (2nd)");
CallMultipleTimes(func);
Console.WriteLine();
Console.WriteLine("once per call");
CallOnce(func);
CallOnce(func);
}
static void CallMultipleTimes(dynamic func)
{
var sw1 = new Stopwatch();
var sw2 = new Stopwatch();
var sw3 = new Stopwatch();
sw1.Start();
func();
sw1.Stop();
sw2.Start();
func();
sw2.Stop();
sw3.Start();
func();
sw3.Stop();
Console.WriteLine("1st: " + sw1.ElapsedTicks.ToString());
Console.WriteLine("2nd: " + sw2.ElapsedTicks.ToString());
Console.WriteLine("3rd: " + sw3.ElapsedTicks.ToString());
}
static void CallOnce(dynamic func)
{
var sw = new Stopwatch();
sw.Start();
func();
sw.Stop();
Console.WriteLine(sw.ElapsedTicks.ToString());
}
}
Which outputs something like:3 times per call (1st)
1st: 123257
2nd: 38059
3rd: 37722
3 times per call (2nd)
1st: 114
2nd: 93
3rd: 76
once per call
38188
112
I tried profiling method calls, but the results aren't very assuming (70% in V8ScriptEngine.ctor, some 20% in Action.Invoke). I wonder if there is any way to mitigate this, beside creating a method just for calling functions? If it's not a ClearScript problem could ClearScript be modified to workaround, or it has to be left up to the application?Thanks!