Transfer object as JavaScript object

Dec 21, 2015 at 8:07 AM
Hi!
We're using ClearScript V8 to render React on the server. Works great, but it slows down a bit when there's a lot of data that needs to be passed to V8. Our current approach is to serialize the object to a JSON string and do: Engine.Evaluate("someFunc(" + json + ")")

Is there a better way to transfer a large object? I looked at adding it as a host object, but from what I can tell it doesn't become real JavaScript objects. That is, a List won't become an array on the JavaScript side, etc.
Dec 21, 2015 at 12:14 PM
I changed the code to expose a Dictionary<string, object> on Engine.Script instead, and iterate over that and convert it to a real JS object. But that turned out to be more than twice as slow as Engine.Evaluate("someFunc(" + json + ")"). I'm guessing it's because I'm crossing the boundary between CLR and V8 a lot by doing that.

Is there any way to create a real JS object from C# and expose that to the script engine?
Coordinator
Dec 21, 2015 at 1:45 PM
Edited Dec 21, 2015 at 1:47 PM
Hello!

You're already doing the right thing by using JSON to minimize hops across the .NET-V8 boundary.

Your next optimization might be to minimize your use of V8's JavaScript parser. To that end, consider wrapping someFunc in a helper that takes a JSON string and converts it via the JSON object:
dynamic someFuncHelper = Engine.Evaluate(@"
    (function (json) {
        return someFunc(JSON.parse(json));
    }).valueOf()
");
Then, simply do this:
// Engine.Evaluate("someFunc(" + json + ")");
someFuncHelper(json);
This way you're using an efficient, dedicated JSON parser to convert your object instead of V8's general-purpose JavaScript parser, which is much more complex. Don't forget to cache and reuse someFuncHelper to avoid re-parsing and recompiling the wrapper.

Good luck!
Dec 21, 2015 at 2:24 PM
Thanks for the tip, I'll try it and report back!
Dec 22, 2015 at 12:39 PM
Using JSON.parse instead of embedding the JSON in the call expression didn't make a difference in performance unfortunately.

Are there any plans on integrating ClearScript with Chakra now that Chakra is going open source?
Coordinator
Dec 22, 2015 at 4:57 PM
Edited Dec 22, 2015 at 5:05 PM
Hi again,

A test that generates large JSON structures (source code here) reveals that V8's JSON parser is 3-4 times as fast as its JavaScript parser, at least when it comes to processing JSON. Consider also that JavaScript parsers are not 100% JSON-compliant (link).

Of course, this test uses very large JSON blocks (~7.5 million characters each) and may not be representative of your application. By using a trivial someFunc, it does isolate the performance of object transfer and conversion. Is it possible that your performance issues are within your someFunc implementation?

We're looking at adding support for the Edge version of Chakra, but that's at a very early stage.

Cheers!