[英]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:以下是一些可能会改进的猜测和建议:
.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.更喜欢使用索引器和/或将其存储在局部变量中。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.