Channel: ClearScript
Viewing all articles
Browse latest Browse all 2297

New Post: 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.

Or am I doing something terrible wrong?
publicvoid ParseDynamic(DynamicObject o) {
            var props = o.GetDynamicMemberNames();

            bool isArray = true;
            // try cast to inttry {
                foreach (var k in props) { Int32.Parse(k); }
            } catch { isArray = false; }

            if (!isArray)
            else {
                foreach (var k in props) { AddRow((DynamicObject)GetMember(o, k)); }


privatevoid AddRow(DynamicObject obj) {
            var cols = obj.GetDynamicMemberNames();
            var row = new MiDataRow(this);

            // Add all columnsforeach (var col in cols) {
                if (!columns.Contains(col)) {

                row[col] = GetMember(obj, col).ToString();


privatestaticobject GetMember(DynamicObject o, string propName) {
            var binder = Binder.GetMember(CSharpBinderFlags.None,
                  propName, o.GetType(),
                  new List<CSharpArgumentInfo>{
                               CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null)});
            var callsite = CallSite<Func<CallSite, object, object>>.Create(binder);

            return callsite.Target(callsite, o);

Viewing all articles
Browse latest Browse all 2297

Latest Images

Trending Articles

Latest Images