簡體   English   中英

如何提高過濾列表的速度

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

我在數據網格中顯示數據,並希望使用范圍滑塊(帶有兩個手柄的滑塊)過濾數據。 范圍 slider 的更改事件僅設置字符串變量filterTrigger 過濾器本身是通過 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 = "";
    }
}

當我注釋掉所有以丟棄_開頭的行時,代碼運行流暢。 但當然,我需要這些線條。 問題是,它們需要大量的處理器能力。 它仍在工作,但是當我點擊過濾器的手柄移動鼠標時,手柄非常滯后(我的筆記本電腦聽起來像直升機)。

我知道最后一個過濾器的一部分是多余的,因為當 filterTrigger 是 foo 時, foo 已經被過濾了。 但是只過濾之前沒有過濾的,並不能單獨解決問題,因為上面我只展示了兩個過濾器,但實際上有大約十個過濾器。

那么,有沒有辦法優化這段代碼?

優化代碼時,第一條規則是測量,最好使用一個分析器,它可以准確地告訴你代碼的哪一部分花費了大部分時間。

第二條規則是使用最佳算法,但除非你有大量的項目和一些合理的方式來對所述項目進行排序或索引,否則線性時間是你能做的最好的。

以下是一些可能會改進的猜測和建議:

  • 避免使用.ElementAt ,這可能會創建一個新的枚舉器 object,這需要一些時間。 尤其是在內部循環中。 更喜歡使用索引器和/或將其存儲在局部變量中。
  • 避免使用 Linq。 Linq 的可讀性很好,但會產生一些開銷。 因此,在優化時,可能值得使用常規循環來查看開銷是否很大。
  • 嘗試在一個 go 中完成所有處理。 而是遍歷所有項目一次以找到最小值,一次遍歷最大值,同時進行這兩項操作。 Memory 速度很慢,並且在已經緩存的項目中盡可能多地處理它有助於減少 memory 流量。
  • 我會考慮將RemoveAll替換為一個循環,該循環將通過檢查的項目復制到一個空列表中。 這應該有助於確保項目最多被復制一次。

優化時的經驗法則是使用低級語言功能。 這些通常更容易使抖動得到很好的優化。 但這可能會使代碼更難閱讀,因此請使用分析器來優化最需要它的地方。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM