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
. The filter itself is triggered via mouseup event.
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. 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. 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. 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.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.