在比较枚举时将1,000多个字符串转换为小写比手动检查不同的变化更便宜

本文关键字:检查 变化 枚举 比较 转换 字符串 | 更新日期: 2023-09-27 18:05:23

我有一个名为SelectedSections的属性,它是从一个section集合中分配的。每个Section包含一个BidItems集合,其中包含1000多个项目。当我选择一个Section时,我需要用一组经过过滤的项来刷新视图绑定到的项集合。

public Section SelectedSection
{
    get 
    { 
        return selectedSection; 
    }
    set 
    {
        this.SetPropertyByReference(ref this.selectedSection, value);
        if (value != null)
        {
            this.BidItems = value.BidItems
                .Where(item => 
                    !item.Description.ToLower().Contains("flagger") ||
                    !item.Description.ToLower().Contains("civilian flagger") ||
                    !item.Description.ToLower().Contains("law enforcement"))
                .ToList();
        }
        this.MptPayment.EditedItem.DiaryPayItem.Section = value;
    }
}

我必须过滤掉大约十几个不同类型的项目(为了清晰起见,我只显示了3个)。在我的Where子句中,在检查集合是否包含我要过滤掉的内容之前,我将所有内容转换为小写。

我意识到这将产生大量的垃圾,因为集合中1000 +项中的每一个都将为小写Description内容创建一个新字符串。我的问题是,对收藏中的每一件物品进行十几次这样的操作是否比我只是检查所有已知的变化更昂贵?忽略了我可能会错过一个变化的事实,因为我对哪个更快的理论更感兴趣。

  1. 野生鸢尾花
  2. 野生鸢尾花
  3. 野生鸢尾花

上面的列表是所有已知的变化。我想知道哪条路线更贵。遍历集合以检查每个已知条件将足够快,而不会产生如此多的垃圾开销。要么,每个项目/描述枚举一次以上以便找到它们,要么在堆上创建垃圾字符串时枚举每个项目/描述一次,这些字符串将被GC。

注意,当用户执行他们的工作时,这个属性可以被重新设置几十次。因此将执行大量(数以万计)的字符串比较。

我意识到相对于应用程序的其余部分,这是一个便宜的操作;我想知道更多的自我教育,而不是担心实际应用程序中的性能影响。

在比较枚举时将1,000多个字符串转换为小写比手动检查不同的变化更便宜

ToLower()对大型收集会产生不必要的GC压力。相反,使用IndexOf >= 0StringConparison.OrdinalIgnoreCase:

this.BidItems = value.BidItems
            .Where(item => 
                !(item.Description.IndexOf("flagger", StringComparison.OrdinalIgnoreCase) >= 0) ||
                !(item.Description.IndexOf("civilian flagger", StringComparison.OrdinalIgnoreCase) >= 0) ||
                !(item.Description.IndexOf("law enforcement", StringComparison.OrdinalIgnoreCase) >= 0))
            .ToList();

一个个人故事——我在分析我们的应用程序时,看到一个负责XML反序列化的方法发出了大量的字符串,导致我们的应用程序每次运行大约发出1.5GB。这种方法是我们的热门方法。这最终导致一个程序员在每次解析迭代中执行ToLower。通过删除该调用,我每次运行最终节省了超过1GB的分配空间。

当您的收集变大时,您将看到这会导致越来越多的GC压力。