Note that there are some explanatory texts on larger screens.

plurals
  1. POWhat is the fastest way to iterate a dynamic object in C#?
    primarykey
    data
    text
    <h1>Background</h1> <p>I am working on an application that requires the consumption of JSON services on the <em>server</em>, and then repackaging of that JSON into a view model that can be referenced using Razor syntax in the view. Server-side manipulation of this code is a must for various reasons.</p> <p>We are using C#, .NET 4, MVC3, Razor, JsonFx.</p> <p>We currently have code that works just fine, but it is taking up to a minute to iterate 250 items in the received JSON object and this is unacceptable (not to mention baffling). I have already isolated the problem to the following loop; the JSON comes in lightening-fast so that is not the problem. Here is the <em>working but extremely slow</em> code:</p> <pre><code> var reader = new JsonReader(); var json = GetJson(SPListName); var admItems = new List&lt;IDictionary&lt;String, object&gt;&gt;(); dynamic _items = reader.Read(json); //This part is REALLY fast. No problem here. foreach (var itm in _items) { dynamic obj = new ExpandoObject(); foreach (dynamic admObj in itm)//Here begins the slow part. { var item = obj as IDictionary&lt;String, object&gt;; var encodedValue = ""; try { if(admObj.Key == "Title") { encodedValue = admObj.Value.ToString(); }else { encodedValue = admObj.Value[0].ToString(); } } catch (Exception) { encodedValue = admObj.Value.ToString(); } item[admObj.Key] = encodedValue.EncodeNonAscii().FixHtmlEntities(); } admItems.Add(obj); } return admItems; </code></pre> <p>You may also notice a few custom extension methods. Here they are (in case that matters):</p> <pre><code>public static string EncodeNonAscii(this Object str) { StringBuilder sb = new StringBuilder(); foreach (char c in str.ToString()) { if (c &gt; 127) { // This character is too big for ASCII string encodedValue = "\\u" + ((int) c).ToString("x4"); sb.Append(encodedValue); } else { sb.Append(c); } } return sb.ToString(); } public static string FixHtmlEntities(this Object str) { var fixedString = str.ToString().Replace("\\u00c2\\u00ae", "&amp;reg;"); return fixedString; } </code></pre> <h1>Question</h1> <p>What the heck am I doing wrong/how do I speed this up. My brain is hamburger right now so I hope someone points out a simple oversight.</p> <h1>Update/Resolution</h1> <p>Rophuine and Joshua Enfield both pointed to the root of the speed issue: the catching of exceptions was slowing everything down. </p> <p>Many folks suggested that I use Json.Net or something similar. While I appreciate that advice, it really wasn't at the root of my problem (even though it may have appeared that way); I have used Json.Net extensively in the past and came to prefer <a href="http://jsonfx.net/" rel="nofollow">JsonFx</a> over it a few months ago. In this particular case, I am more concerned with the <em>construction</em> of a view model object as I have already deserialized the JSON using JsonFx. Please let me know if you still think I am missing your point ;).</p> <p>The reason for my brain-dead try/catch scheme was that I needed to do different things with each property of the JSON string depending on it's type (string, string[], object[], etc). I forgot that System.Type can handle that for me. So here is the final code:</p> <pre><code>var reader = new JsonReader(); var json = GetJson(SPListName); var admItems = new List&lt;IDictionary&lt;String, object&gt;&gt;(); dynamic _items = reader.Read(json); foreach (var itm in _items) { dynamic obj = new ExpandoObject(); foreach (dynamic admObj in itm) { var item = obj as IDictionary&lt;String, object&gt;; var encodedValue = ""; Type typeName = admObj.Value.GetType(); switch (typeName.ToString()) { case("System.String[]"): encodedValue = admObj.Value[0].ToString(); break; default: encodedValue = admObj.Value.ToString(); break; } item[admObj.Key] = encodedValue.EncodeNonAscii().FixHtmlEntities(); } admItems.Add(obj); } return admItems; </code></pre> <p>Hope this helps someone!</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload