ScriptItem performance

I noticed some performance issues with the usage of ScriptItem.
What I did was I had a constructor which received a script item as argument. And because ScriptItem has accessors set to internal, I had to use it as DynamicObject or dynamic.

What I wanted was to create a flat table of the object, just by getting the object keys as column name and their values as row values. The Properties are retrieved with the "GetDynamicMemberNames()" function, so no problems there. But for each of
the properties I needed to create a Binder and get the value (see code below)

Now anybody can guess that this is not very fast. I tried to create a simple table with 3 rows and 13 columns. And it took a good +/- 1500 milliseconds on one run. I did the same with JSON.net JObject and because accessing properties isn't such a hassle their
I got a performance of 0 milliseconds on one run. My temporary fix is that I call JSON.stringify before the constructor and in the constructor I uses JSON.NET his parser.

Anyway, my question or point of discussion: Isn't ScriptItem flawed by design? Why the use of dynamics? Take a look at how JSON.net encodes JS objects with strict types. In essence are all JS Objects KeyValuePairs where the Value types can vary.

​
.NET's dynamic infrastructure provides a convenient way to access script objects in a way that's both .NET-friendly and engine-neutral. A dictionary-style interface might also be convenient, but it's not clear what advantage it would have over the combination
of GetDynamicMemberNames() and dynamic indexing.

The problem with your GetMember() method is that it recreates the binder and callsite each time. Try this instead:

This implementation is simpler and takes advantage of inline caching to speed up repeated calls. In our experiments it's about 22x faster on average in Release builds.

Still, using JSON tunneling as you suggest makes sense in many cases. ClearScript provides live access to script objects, but if all you need is a snapshot, then JSON is a great way to minimize marshaling and improve performance.

It is still +/- 60 milliseconds (ScriptItem) against +/- 3 milliseconds (String -> Json.net) on the initial run. But after that the JIT has optimized both to nano seconds.
So thanks! These differences can be explained by the fact that on the first run the JIT will optimize a part of the code path the seconds also takes.

I will look more into it and do some better benchmarks to see which one is really faster. Still I expect that the String version is faster.
If that is the cast that really is such a shame.
But more on this later, thanks anyway!

Both the strJson and the JSON function implement the same idea, but the strJson de-serialises the string, and still managed to be faster.
My point stays, isn't it better to not make ScriptItem dynamic. Because within Javascript all object can be of fixed types and all objects are key value pairs anyway. Or maybe is it possible to make use of JSON.net JObject instead of dynamic ScriptItem? Even
translating the ScriptItem to JObject results in a higher benchmark than the above benchmark.

Anyway, thanks for your time and I hope you can do something with my findings.

The purpose of a script item in ClearScript is to allow .NET code to access an actual "live" script object, as opposed to a serialized copy of its data.

Yes, it's definitely faster to read data from a managed collection such as a Json.NET
JObject or a standard .NET dictionary - and if reading a script object's properties quickly is what you need to do, then we encourage and recommend JSON tunneling. Hopping the boundary between the managed and script environments is expensive, and
JSON lets you transfer an entire object's data in one hop.

However, this is very different from what script items do. Some examples:

Writing to a script item modifies the actual script object to which it's bound.

Unlike JSON, script items provide access to JavaScript properties that are not enumerable.