为了查看慢的地方,添加了一些日志记录。其中遍历1w次便会输出一次时间。
优化前
优化后
优化后
服务器cpu使用高,很可能是数据已经获取到,计算机一直处于快速计算中。从前面日志也证实了这点。
``
result.ForEach(item =>
{
// 省略一部分,简单的判断和赋值
var trackingList = wobTrackingList.Where(m => m.WOBShipOrderID == item.OrderId);
if (trackingList.IsStrictSafed())
{
item.ParentTrackingNo = trackingList.FirstOrDefault(m => m.IsParentTrackingNo)?.TrackingNo;
var trackNos= trackingList.Where(m => !m.IsParentTrackingNo).Select(m=>m.TrackingNo);
item.TrackingNo = string.Join(",", trackNos);
}
// 省略一部分,简单的判断和字典中取值。
// 省略一部分,字符序列化成对象然后取值赋值。前面优化后,进行测试,证明这里也不影响处理速度。
});
``
其中 wobTrackingList也是提前查询出来的。看似都在内存中计算,应该会很快的。但是忽略了两点。1、Where 运算实际上是查询运算,虽然别人给我们封装好了,单次调用速度很快,但是也比赋值加减运算要慢。2、wobTrackingList中的数据量很可能比外层遍历的数据还要大。wobTrackingList数量越大,Where耗时越多。加之外圈遍历次数多了,累计耗时就上去了。
将wobTrackingList 转化成字典。循环中只做取值赋值操作。
var trackingDic = new Dictionary<Guid, (string parentTrackingNo, string trackNos)>();
wobTrackingList.GroupBy(m => m.WOBShipOrderID).ToList().ForEach(t => {
var parentTrackingNo = t.FirstOrDefault(m => m.IsParentTrackingNo)?.TrackingNo;
var trackNos = string.Join(",", t.Where(m => !m.IsParentTrackingNo).Select(m => m.TrackingNo));
trackingDic.Add(t.Key, (parentTrackingNo, trackNos));
});
result.ForEach(item =>
{
if (trackingDic.ContainsKey(item.OrderId))
{
var (parentTrackingNo, trackNos) = trackingDic[item.OrderId];
item.ParentTrackingNo = parentTrackingNo;
item.TrackingNo = trackNos;
}
});