【发布时间】:2018-05-27 00:52:46
【问题描述】:
我正在尝试将 1000 个动态列表(我从 CsvHelper 读取 csv 文件中获得)转换为静态类型,但它需要永远。
代码如下:
动态对象
MyObj {
id =1, prop1=1,prop2=2,prop3=3...
}
结果
PObj1 { oid = 1 , name = "Property 1", value = "1" }
PObj2 { oid = 1 , name = "Property 2", value = "2" }
PObj3 { oid = 1 , name = "Property 3", value = "3" }
要转换的代码
var imp = rows.SelectMany(x => map.Keys.ToList().Select(k => new PObj
{
OID = (((IDictionary<string, object>)x)["oid"] ?? "").ToString(),
Name = k,
Value = ToDate((((IDictionary<string, object>)x)[map[k]] ?? "").ToString())
}).ToList()).ToList();
地图包含大约 40-50 的属性列表
map<string,string>{
{"Property 1","prop1"},
{"Property 1","prop2"},
{"Property 1","prop3"}
...
}
ToDate 函数
private DateTime? ToDate(string strDate)
{
strDate = strDate.Split(' ')[0];
strDate = strDate.Replace('-', '/').Replace('.', '/');
DateTime? dt = null;
try
{
dt = DateTime.ParseExact(strDate, dateFormats, CultureInfo.InvariantCulture, DateTimeStyles.None);
} catch { }
return dt;
}
map 可以包含任意数量的属性,因此 expandoObject 将具有动态数量的属性。
有什么方法可以提高性能吗?
我需要进行此转换的原因是因为我需要将其作为表发送到存储过程,因此如果对象中的数字属性发生更改,则将 expandoObject 直接转换为表会产生问题,因为此平均列数也会在表中更改.
如果在上述情况下工作,我也愿意接受其他解决方案。
【问题讨论】:
-
在代码运行时检查任务管理器并查看内存使用情况。 Linq 对象/方法使用大量内存,执行时间缓慢通常是内存问题。
-
将 ParseExact 更改为 TryParseExact 并查看是否有所作为。假设 ParseExact 有 90% 的时间都失败了,那么这意味着你会产生很多异常,它们是性能杀手
-
@JoostAarts 没有任何区别。顺便说一句,它的逆转,它成功了几乎 95% 的时间
-
我一定是做错了什么,它只有大约 15k 的动态对象,有 8 个属性,应该创建大约 130k 的对象,这不是很大的数字,但它仍然需要永远
-
不确定如何,但相同的代码(几乎相同)现在可以正常工作。它在不到一秒的时间内完成了整个列表。 rows.ToList().ForEach(x => imps.AddRange(map.Keys.Select(k => new ImportMilestone { JVSiteID = (((IDictionary
)x)[siteid] ?? ""). ToString(), Milestone = k, MilestoneValue = ToDate((((IDictionary )x)[map[k]] ?? "").ToString()) }).ToList()));
标签: c# .net performance dynamic expandoobject