通过DrawingCollection迭代与使用Contains()的速度

时间:2011-11-11 08:08:54

标签: c# .net wpf optimization

我有一个显示Equipments集合的WPF组件。这些Equipments中的每一个都包含一个或多个Coordinate。在我的组件MouseMove上,调用一个函数来检查鼠标当前是否在任何Coordinate的任何Equipment范围内徘徊。如果是,则返回有问题的Equipment,表示应显示包含Equipment文本信息的弹出窗口。

除此之外,所有Coordinates都包含ImageDrawing,其中显示每个Equipment的符号(用户将鼠标悬停在符号上以查看文本弹出窗口的符号)。这些被放在一个单独的DrawingGroup中以加快渲染速度。这样做的另一个好处是,如果要隐藏某些Equipments,我们只需从Coordinates' ImageDrawing中移除DrawingGroup,它们仍将保留在Equipments列表中(他们应该这样做。)

但是,当鼠标悬停在Coordinate上时,这不会阻止显示弹出窗口,因为它与DrawingGroup分开。因此,要检查是否要显示文本弹出窗口,我必须同时检查鼠标是否在任何Coordinate的范围内,并检查ImageDrawing是否为Coordinate在} DrawingGroup

关于我的问题(tl; dr):迭代所有这些项目的哪种方式会最快?我有:

List<Equipment> equipments;

对于这些中的每一个(这个列表中的9个中有9个包含一个项目,并且从不超过5个)

List<Coordinate> coordinates;

对于这些Coordinates中的每一个,我必须检查他们的ImageDrawing是否在DrawingCollection(在这种情况下是DrawingGroup.Children)中,根据到msdn,是ordered collection of Drawing objects.

为此,我从这开始:

foreach (Equipment equipment in equipments)
{
    foreach (Coordinate coordinate in equipment.Coordinates)
    {
        ImageDrawing image = coordinate.ImageDrawing;
        if (image != null)
        {
            if (currentDrawingGroup.Children.Contains(image))
            {
                if (image.Rect.Bottom > y && 
                    image.Rect.Top < y && 
                    image.Rect.Left < x && 
                    image.Rect.Right > x)
                {
                    return equipment;
                }
            }
        }
    }
}

但是认为在隐藏了大量设备的情况下,这会变成许多迭代,并且我可以将其更改为此(因为Children.Contains(image)无论如何都可以在幕后迭代):

foreach (var child in currentDrawingGroup.Children)
{
    foreach (Equipment equipment in equipments)
    {
        foreach (Coordinate coordinate in equipment.Coordinates)
        { 
            ImageDrawing image = coordinate.ImageDrawing;
            if (image != null)
            {
                if (image == child)
                {
                    if (image.Rect.Bottom > y && 
                        image.Rect.Top < y && 
                        image.Rect.Left < x && 
                        image.Rect.Right > x)
                    {
                        return equipment;
                    }
                }
            }
        }
    }
}

我知道这个问题太长了,从长远来看,我在这里看到的优化可能并不重要。但有没有办法可以在循环中没有这么多循环的情况下完成?我觉得应该有一个LINQ表达式帮助我,虽然我不知道其中任何一个是否比foreach循环更快。对事物进行排序的方式(Equipments通过从DrawingGroup中删除它们而隐藏它们)是我无法控制的,很难改变。非常感谢。

1 个答案:

答案 0 :(得分:1)

如果要隐藏某些设备,让设备自己管理其可见性会不会更清洁?这样你只要先询问设备是否可见,如果没有则跳过它?

因此,您的设备也始终存在,但是可见或不可见,当您将鼠标悬停时,您无需检查坐标是否在DrawingGroup中......它已经为您处理了。

关于迭代vs Contains(),contains函数是一个线性搜索,因此它与迭代列表相同。