Quantcast
Channel: ClearScript
Viewing all articles
Browse latest Browse all 2297

New Post: V8ScriptEngine.Compile vs. V8ScriptEngine.Script

0
0
Hello sgammans!

Your first technique above (the one that goes through ScriptEngine.Script) is the right way to invoke an existing script function multiple times. We'd actually recommend caching a reference to the function:
V8ScriptEngine engine = new V8ScriptEngine();
engine.Execute(code);
dynamic computeFoo = engine.Script.computeFoo;
for (int i = 0; i < 50000; i++)
{
    var result = computeFoo(getFoo(i));
    // do something here with result
}
Your second code sample executes the same function statement over and over, needlessly redeclaring the function 50000 times. In addition to making it difficult to pass arguments, this could create 50000 copies of the function for the garbage collector to clean up. We say could because V8 might be smart enough to optimize the duplicate functions away.

Frankly we're surprised that the second technique is faster. Our suspicion is that this is because (a) computeFoo() is trivial, and (b) V8 is very good at avoiding duplicate work.

By the way, in your second code sample, the line foo = getFoo(i); only reassigns the .NET variable foo; it does not affect the script variable hostFoo. If we're reading your code correctly, this means that computeFoo() will operate on the same Foo instance every time. The code should probably be something like this instead:
V8ScriptEngine engine = new V8ScriptEngine();
// Foo foo = new Foo();// engine.AddHostObject("hostFoo", foo);
V8Script compiledCode = engine.Compile(code);
for (int i = 0; i < 50000; i++)
{
    // foo = getFoo(i);
    engine.Script.hostFoo = getFoo(i);
    var result = engine.Evaluate(compiledCode);
    // do something here with result
}
But again, the other way is much better. It's simpler and cleaner, and it should be faster and more efficient in real-world situations.

If you're wondering then what the point of compilation is, consider a scenario where your client provides arbitrary script code (not a single script function) that you must execute many times. In this situation, the following:
void ExecuteManyTimes(V8ScriptEngine engine, string code, int repeatCount)
{
    using (var compiledCode = engine.Compile(code))
    {
        for (var i = 0; i < repeatCount; i++)
        {
            engine.Evaluate(compiledCode);
        }
    }
}
is much faster than this:
void ExecuteManyTimes(V8ScriptEngine engine, string code, int repeatCount)
{
    for (var i = 0; i < repeatCount; i++)
    {
        engine.Evaluate(code);
    }
}
In addition, compiled scripts can be shared among multiple V8ScriptEngine instances that share a single V8Runtime.

Cheers!

Viewing all articles
Browse latest Browse all 2297