在ANTs分析器信息的帮助下识别性能瓶颈

时间:2012-11-27 17:11:33

标签: c# linq profiler red-gate-ants

此代码运行缓慢:

public static class DB
    {
        readonly static InlineSql sql = new InlineSql();

        public static IEnumerable<LabItem> GetLabItemsFromLabLineItems(IEnumerable<LabLineItem> items)
        {
            /*
             * Business Rule : 
             * The sproc used to retrieve lab line items has no way of "grouping" lab items out of line items.
             * To compensate, the sproc orders its results by IDCode, we group everything and use the first of each grouping to represent that ID Code.
             * That very same item is also the first item in its Items property.
             * */
            return items
                .GroupBy(c => c.IDCode , c => c, (c, d) => d.First())
                .Select(c => new LabItem(c.IDCode, c.OrderGuid, c.Name, c.SignificantDtm, c.Status, c.Description, items.Where(d => string.Compare(d.IDCode, c.IDCode, true) == 0 )));
        }        
    }

特别是我们将d.IDCode与c.IDCode进行比较的select语句似乎是个问题。该行报告来自ANTS的命中数为9000万,时间百分比为14.8。 items.count约为9,000。

我知道我的断点没有达到9000万次。点击计数在这里意味着什么?

其他有用的代码:

LabItemList<LabLineItem>,这是我们在此比较的内容。 LabLineItem.Equals

    public override bool Equals(object obj)
    {
        LabLineItem otherItem = obj as LabLineItem;

        if (otherItem == null) return false;

        return
            OrderGuid == otherItem.OrderGuid
            && IDCode == otherItem.IDCode
            && SignificantDtm == otherItem.SignificantDtm
            && ObservationGuid == otherItem.ObservationGuid
            && string.Compare(Value, otherItem.Value, true) == 0;
    }
    public override int GetHashCode()
    {
        return
            OrderGuid.GetHashCode()
            ^ IDCode.GetHashCode()
            ^ SignificantDtm.GetHashCode()
            ^ ObservationGuid.GetHashCode();
    }

1 个答案:

答案 0 :(得分:4)

ANTS说Select string.Comparestring.Compare次点击次数是9000万次,因为对于主列表中的每个项目,它都会再次搜索整个列表。

每个主要的9000次迭代都会导致9000次额外的迭代,因此LabItem必须至少被调用81,000,000次。

我建议构建分组的缓存,然后使用它来构建var groupedItems = items.GroupBy(c => c.IDCode); return items.Select(c => new LabItem(c.IDCode, c.OrderGuid, c.Name, c.SignificantDtm, c.Status, c.Description, groupedItems.Where(d => string.Compare(d.Key, c.IDCode, true) == 0 ).SelectMany(group => group)));

也许是这样的:

{{1}}