在C#中迭代动态对象的最快方法是什么? 背景

在C#中迭代动态对象的最快方法是什么? 背景,c#,asp.net-mvc,json,dynamic,C#,Asp.net Mvc,Json,Dynamic,我正在开发一个需要在服务器上使用JSON服务的应用程序,然后将该JSON重新打包到视图模型中,该视图模型可以在视图中使用Razor语法引用。出于各种原因,必须在服务器端操纵此代码 我们正在使用C#、.NET4、MVC3、Razor、JsonFx 我们目前的代码工作得很好,但在接收到的JSON对象中迭代250个项目需要一分钟,这是不可接受的(更不用说令人困惑了)。我已经将问题隔离到以下循环中;JSON来得很快,所以这不是问题所在。以下是工作正常但速度极慢的代码: 问题: 我到底做错了什么/我该如何

我正在开发一个需要在服务器上使用JSON服务的应用程序,然后将该JSON重新打包到视图模型中,该视图模型可以在视图中使用Razor语法引用。出于各种原因,必须在服务器端操纵此代码

我们正在使用C#、.NET4、MVC3、Razor、JsonFx

我们目前的代码工作得很好,但在接收到的JSON对象中迭代250个项目需要一分钟,这是不可接受的(更不用说令人困惑了)。我已经将问题隔离到以下循环中;JSON来得很快,所以这不是问题所在。以下是工作正常但速度极慢的代码:

问题: 我到底做错了什么/我该如何加快速度。我的大脑现在是汉堡,所以我希望有人指出一个简单的疏忽

更新/决议 罗普休恩和约书亚·恩菲尔德都指出了速度问题的根源:捕捉异常正在减缓一切

许多人建议我使用Json.Net或类似的东西。虽然我很欣赏这个建议,但它并不是我问题的根源(尽管它可能看起来是这样);过去我广泛使用Json.Net,几个月前我就开始喜欢它了。在本例中,我更关心视图模型对象的构造,因为我已经使用JsonFx反序列化了JSON。如果你仍然认为我没有抓住你的重点,请告诉我;)

我之所以采用“脑死”的try/catch方案,是因为我需要根据JSON字符串的类型(字符串、字符串[]、对象[]等)对每个属性执行不同的操作。我忘了那个系统了。打字机可以帮我处理。这是最后的代码:

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;
var reader=newjsonreader();
var json=GetJson(SPListName);
var admItems=新列表();
动态_items=reader.Read(json);
foreach(项目中的var itm)
{
动态对象=新的ExpandooObject();
foreach(itm中的动态admObj)
{
var项目=作为IDictionary的obj;
var encodedValue=“”;
键入typeName=admObj.Value.GetType();
开关(typeName.ToString())
{
大小写(“System.String[]”:
encodedValue=admObj.Value[0].ToString();
打破
违约:
encodedValue=admObj.Value.ToString();
打破
}
item[admObj.Key]=encodedValue.EncodeNonAscii().FixHtmlEntities();
}
添加(obj);
}
回信;
希望这对别人有帮助

            try
            {
                if(admObj.Key == "Title")
                {
                    encodedValue = admObj.Value.ToString();
                }else
                {
                    encodedValue = admObj.Value[0].ToString();
                }
            }
            catch (Exception)
            {
                encodedValue = admObj.Value.ToString();                   
            }
我面前没有C#编译器,也无法访问您的数据,但我觉得这很可疑。异常非常缓慢-您是否经常碰到捕捉块?如果你是,试着找出导致异常的原因,并在不导致异常的情况下处理它们——让异常处理你没有想到的罕见情况


编辑:最终的解决方案是在问题编辑-我不会在这里重复它。如果您有性能问题,并且在循环中的某个地方有异常处理,那么这通常是第一件要尝试和消除的事情。异常非常缓慢——比你想象的要慢得多。它们最好保存在非常不寻常的情况下。

发生了多少例外情况?如果是边界线流量控制,异常处理可能会使您的速度减慢一些,但对于250个项目来说,一分钟听起来太长了。您真的需要在这里使用dynamic吗?是否有任何理由不使用json库,如json.NET或ServiceStack.NET?解析json字符串更容易(也更快速)。除了@Ni'am之外,您还可以使用一行代码
JsonConvert.DeserializeObject
创建一个对象字典。例子:我认为@JoshuaEnfield和Rophuine在钱上。不幸的是,发布JSON的服务器刚刚宕机。啊!很快会让你们知道的。谢谢@MatthewPatrickCashatt,我也认为您的问题与异常有关,但使用for ex,Json.Net可以帮助您用一行代码替换您发布的所有代码(不再有异常)干杯Rophuine!谢谢你的帮助。请查看上面我的最终更新,并在您认为合适的情况下将其任意一个合并到您的答案中。显然,异常只在调试模式下运行缓慢,但正如名称所暗示的,异常应该是异常,而不是规则。
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;
            try
            {
                if(admObj.Key == "Title")
                {
                    encodedValue = admObj.Value.ToString();
                }else
                {
                    encodedValue = admObj.Value[0].ToString();
                }
            }
            catch (Exception)
            {
                encodedValue = admObj.Value.ToString();                   
            }