简体   繁体   English

如何提高过滤列表的速度

[英]How can I increase the speed of filtering a list

I display data in a data grid and want to filter the data with range sliders (slider with two handles).我在数据网格中显示数据,并希望使用范围滑块(带有两个手柄的滑块)过滤数据。 The change-event of the range slider only sets the string variable filterTrigger .范围 slider 的更改事件仅设置字符串变量filterTrigger The filter itself is triggered via mouseup event.过滤器本身是通过 mouseup 事件触发的。

private void ApplyFilter()
{
    if (filterTrigger != "")
    {
        filteredData.Clear();

        suitableData.ForEach((item) =>
        {
            filteredData.Add(item); // create not referenced copy of list suitableData that was created in time consuming calculations
        });

        switch (filterTrigger)
        {
            case "foo":
                // remove too small and too large Foos
                _ = filteredData.RemoveAll(x => x.Foo > fooRangeSliderHandlesMinMax.ElementAt(1) || x.Foo < fooRangeSliderHandlesMinMax.ElementAt(0));
                // set new minimum and maximum of range of range slider
                barRangeSliderMinimum = filteredData.Min(x => x.Bar) - 0.1;
                barRangeSliderMaximum = filteredData.Max(x => x.Bar) + 0.1;
                // set new position of range slider handles
                barRangeSliderHandlesMinMax = new double[2] { Math.Max(barRangeSliderHandlesMinMax.ElementAt(0), barRangeSliderMinimum + 0.1), Math.Min(barRangeSliderHandlesMinMax.ElementAt(1), barRangeSliderMaximum - 0.1) };
                break;
            case "bar":
                _ = filteredData.RemoveAll(x => x.Bar > barRangeSliderHandlesMinMax.ElementAt(1) || x.Bar < barRangeSliderHandlesMinMax.ElementAt(0));
                fooRangeSliderMinimum = filteredData.Min(x => x.Foo) - 0.1;
                fooRangeSliderMaximum = filteredData.Max(x => x.Foo) + 0.1;
                fooRangeSliderHandlesMinMax = new double[2] { Math.Max(fooRangeSliderHandlesMinMax.ElementAt(0), fooRangeSliderMinimum + 0.1), Math.Min(fooRangeSliderHandlesMinMax.ElementAt(1), fooRangeSliderMaximum - 0.1) };
                break;
            default:
                break;
            }

        // remove values of foo if filterTrigger was "bar" and vice versa
        _ = filteredData.RemoveAll(x => x.Foo > fooRangeSliderHandlesMinMax.ElementAt(1) || x.Foo < fooRangeSliderHandlesMinMax.ElementAt(0) || x.Bar > barRangeSliderHandlesMinMax.ElementAt(1) || x.Bar < barRangeSliderHandlesMinMax.ElementAt(0));

        // update data grid data
        IFilteredData = filteredData;

        dataGrid.Reload();

        filterTrigger = "";
    }
}

The code is working fluently when I comment out all the lines that start with a discard _ .当我注释掉所有以丢弃_开头的行时,代码运行流畅。 But of course, I need these lines.但当然,我需要这些线条。 The problem is, that they need much processor power.问题是,它们需要大量的处理器能力。 It is still working but when I move the mouse with clicked handle of a filter, the handle is extremely lagging (and my laptop sounds like a helicopter).它仍在工作,但是当我点击过滤器的手柄移动鼠标时,手柄非常滞后(我的笔记本电脑听起来像直升机)。

I know that a part of the last filter is redundant, because when filterTrigger is foo, foo was already filtered.我知道最后一个过滤器的一部分是多余的,因为当 filterTrigger 是 foo 时, foo 已经被过滤了。 But filtering only what was not filtered before, will not alone solve the problem, because above I only show two filters but there are actually about ten filters.但是只过滤之前没有过滤的,并不能单独解决问题,因为上面我只展示了两个过滤器,但实际上有大约十个过滤器。

So, is there a way I could optimize this code?那么,有没有办法优化这段代码?

When optimizing code the first rule is to measure, preferably with a profiler that can tell you exactly what part of the code takes most of the time.优化代码时,第一条规则是测量,最好使用一个分析器,它可以准确地告诉你代码的哪一部分花费了大部分时间。

Second rule would be to use a optimal algorithm, but unless you have a huge number of items and some reasonable way to sort or index said items, linear time is the best you can do.第二条规则是使用最佳算法,但除非你有大量的项目和一些合理的方式来对所述项目进行排序或索引,否则线性时间是你能做的最好的。

Here are some guesses and suggestions of things that might be improved:以下是一些可能会改进的猜测和建议:

  • Avoid using .ElementAt , this might create a new enumerator object, and that will take some time.避免使用.ElementAt ,这可能会创建一个新的枚举器 object,这需要一些时间。 Especially inside inner loops.尤其是在内部循环中。 Prefer to use indexers and/or store it in local variables instead.更喜欢使用索引器和/或将其存储在局部变量中。
  • Avoid using Linq.避免使用 Linq。 Linq is great for readability, but it will have some overhead. Linq 的可读性很好,但会产生一些开销。 So when optimizing it might be worthwhile to use regular loops to see if the overhead is significant or not.因此,在优化时,可能值得使用常规循环来查看开销是否很大。
  • Try to do all processing in one go.尝试在一个 go 中完成所有处理。 Instead iterating over all items once to find the minimum and once to do the maximum, do both at the same time.而是遍历所有项目一次以找到最小值,一次遍历最大值,同时进行这两项操作。 Memory is slow, and by doing as much processing of an item as possible when it is already cached helps reduce memory traffic. Memory 速度很慢,并且在已经缓存的项目中尽可能多地处理它有助于减少 memory 流量。
  • I would consider replacing RemoveAll with a loop that copies items that pass the check to a empty list.我会考虑将RemoveAll替换为一个循环,该循环将通过检查的项目复制到一个空列表中。 This should help ensure items are copied at most once.这应该有助于确保项目最多被复制一次。

A rule of thumb when optimizing is to use low level language features.优化时的经验法则是使用低级语言功能。 These are often easier for the jitter to optimize well.这些通常更容易使抖动得到很好的优化。 But it may make the code harder to read, so use a profiler to optimize the places that need it the most.但这可能会使代码更难阅读,因此请使用分析器来优化最需要它的地方。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 XNA-如何提高精灵速度 - XNA - how can i increase my sprite speed 如何加快ListBox渲染和ListCollectionView过滤? - How can I speed up ListBox rendering and ListCollectionView filtering? 如何根据达到的转速值决定何时降低转速以及何时提高转速? - How can I decide when to decrease the rotation speed and when the increase depending on the speed reached value? 当一个玩家彼此靠近时,如何降低一个玩家的速度并提高另一个玩家的速度? - How Can I reduce speed of one player and increase speed of another player when it comes closer to one another? 我可以提高我的 DataTable 和 List&lt;&gt; 迭代速度吗? C# - Can I increase my DataTable and List<> iteration speed. C# 如何提高敌人的速度? - How to do I increase the speed of enemies? 如何在Window应用程序中使用winmm.dll提高音频文件的速度 - How can i increase speed of audio file using winmm.dll in Window Application 如何逐渐向 Object 增加更多的力量来提高它的速度,不管它的方向是什么? - How Can I Gradually Add More Force To An Object To Increase It's Speed Regardless of It's Direction? 如何提高反序列化速度? - How to increase deserialization speed? 如何在 api 调用列表中加快或提高效率? - How to speed up or Increase efficiency in a list of api calls?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM