фон
Я работаю над приложением, которое требует потребления JSON услуг на сервере, а затем переупаковка этого JSON в модели представления, которые можно ссылаться с использованием синтаксиса Razor в представлении. Обработка на стороне сервера этого кода является обязательной по различным причинам.Каков самый быстрый способ итерации динамического объекта в C#?
Мы используем C#, .NET 4, MVC3, Razor, JsonFx.
В настоящее время у нас есть код, который работает очень хорошо, но он занимает минуту, чтобы перебрать 250 предметов в полученном объекте JSON, и это неприемлемо (не говоря уже о недоумении). Я уже выделил проблему для следующего цикла; JSON приходит быстро, так что это не проблема. Вот работает, но очень медленно код:
var reader = new JsonReader();
var json = GetJson(SPListName);
var admItems = new List<IDictionary<String, object>>();
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<String, object>;
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;
Вы также можете заметить несколько методов пользовательских расширений. Вот они (в случае, если имеет значение):
public static string EncodeNonAscii(this Object str)
{
StringBuilder sb = new StringBuilder();
foreach (char c in str.ToString())
{
if (c > 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", "®");
return fixedString;
}
Вопрос
Какого черта я делаю неправильно/как я ускорить это. Мой мозг - гамбургер прямо сейчас, поэтому я надеюсь, что кто-то указывает на простой надзор.
Update Разрешение/
Rophuine и Джошуа Enfield и указал на корень вопроса скорости: на отлов исключений было замедляя все вниз.
Многие люди предлагали использовать Json.Net или что-то подобное. Хотя я ценю этот совет, это действительно не лежало в основе моей проблемы (хотя, возможно, это и было так); Я использовал Json.Net в прошлом в прошлом и предпочел JsonFx над ним несколько месяцев назад. В этом конкретном случае я больше интересуюсь конструкцией объекта модели представления, поскольку я уже десериализую JSON с использованием JsonFx. Пожалуйста, дайте мне знать, если вы все еще думаете, что мне не хватает вашей точки;).
Причина, по которой моя мозговая схема try/catch была в том, что мне нужно было делать разные вещи с каждым свойством строки JSON в зависимости от ее типа (строка, строка [], объект [] и т. Д.). Я забыл, что System.Type может справиться с этим для меня. Итак, вот окончательный код:
var reader = new JsonReader();
var json = GetJson(SPListName);
var admItems = new List<IDictionary<String, object>>();
dynamic _items = reader.Read(json);
foreach (var itm in _items)
{
dynamic obj = new ExpandoObject();
foreach (dynamic admObj in itm)
{
var item = obj as IDictionary<String, object>;
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;
Надеюсь, это поможет кому-то!
Сколько исключений происходит?Если обработка обработки исключений в пограничных потоках может замедлить некоторые из них, но минута звучит ужасно долго для 250 предметов. Вам действительно нужно использовать динамику здесь? –
Есть ли причина, по которой вы не используете json-библиотеку, такую как JSON.NET или ServiceStack.NET? Легче (а также быстро) разбирать строку json. –
В дополнение к @ Ni'am, вы можете иметь словарь объектов с одной строкой кода 'JsonConvert.DeserializeObject'. Примеры: http://stackoverflow.com/questions/8662233/parsing-non-standard-json/8662323#8662323 http://stackoverflow.com/questions/8887029/parsing-json-file-c-sharp/8887177#8887177 –