C# 集合。包含大O

C# 集合。包含大O,c#,optimization,collections,big-o,C#,Optimization,Collections,Big O,我需要优化一个显示系统警报数量的功能,当它达到20000个警报时,速度会慢得让人无法忍受。(警报由一个警报和一个条件组成,这意味着它实际上是40000个对象)。此号码每5秒刷新一次 现在,不要介意只需要一个整数,而之前的程序员通过以下方式实现了这一点: 每次呼叫(已确认和未确认)时从数据库加载每个警报和条件 遍历每个报警以查找未确认的报警(使用一些自定义Linq扩展) 向Silverlight应用程序发送未确认报警列表和条件匹配列表 将未确认报警列表与缓存的未确认报警列表进行比较 重复4次。条件

我需要优化一个显示系统警报数量的功能,当它达到20000个警报时,速度会慢得让人无法忍受。(警报由一个警报和一个条件组成,这意味着它实际上是40000个对象)。此号码每5秒刷新一次

现在,不要介意只需要一个整数,而之前的程序员通过以下方式实现了这一点:

  • 每次呼叫(已确认和未确认)时从数据库加载每个警报和条件
  • 遍历每个报警以查找未确认的报警(使用一些自定义Linq扩展)
  • 向Silverlight应用程序发送未确认报警列表和条件匹配列表
  • 将未确认报警列表与缓存的未确认报警列表进行比较
  • 重复4次。条件
  • 将标签绑定到
    报警。计数
    条件。计数
  • 这显然会导致大量不必要的开销,我计划用SQL语句替换所有内容来解决这一问题

    SELECT COUNT(*) as UnAckAlarms
    FROM Alarms
    WHERE AckTime IS NULL
    
    但是没有,我想知道的是第四步。 在那里我发现了这个:

    foreach (var alarm in loadResult.Entities)
    {
        if (!ActiveAlarms.Contains(alarm.AlarmId))
        {
            ActiveAlarms.Add(new AlarmInfo
            (...)
    
    据我所知,Alarm是一个没有散列的对象,所以我想知道。。集合
    .Contains()
    O(n)的bigO是否为?在这种情况下,上面的代码不是有一个O(n^2)吗?而且,如果我通过替换整个集合将代码优化为O(n),甚至O(1),我会得到0.99%的速度提升吗?(40000/400000^2) 或者我应该用SQL语句替换所有内容并重写应用程序的主要部分吗

    编辑:所以,一些结果: 优化前:60秒以上的总get 删除不必要的循环和自定义添加后:8秒~从服务器加载时间为7秒,因此: 服务器端优化后:0.3秒


    这大约是速度提高了200%。)

    假设
    ActiveAlarms
    类型为
    Collection
    List
    ,且未使用哈希实现,则
    Contains()
    的值为O(n),且上述代码的值确实为O(n^2)

    如果可以将
    ActiveAlarms
    更改为散列集合,则
    Contains()
    将为O(1),而上面的整个代码将变为O(n)。问题是O(1)是否实际上比O(n)快得多,这取决于哈希表的内部哈希函数有多复杂。但我认为我们可以肯定,在大多数正常情况下,它会更快

    您将获得的确切速度增长是不可预测的。我得说,测量并找出答案


    祝你好运

    假设
    ActiveAlarms
    类型为
    Collection
    List
    ,且未使用哈希实现,则
    Contains()
    的值为O(n),且上述代码的值确实为O(n^2)

    如果可以将
    ActiveAlarms
    更改为散列集合,则
    Contains()
    将为O(1),而上面的整个代码将变为O(n)。问题是O(1)是否实际上比O(n)快得多,这取决于哈希表的内部哈希函数有多复杂。但我认为我们可以肯定,在大多数正常情况下,它会更快

    您将获得的确切速度增长是不可预测的。我得说,测量并找出答案


    祝你好运

    我会把这整件事转换成sql。创建一组触发器,每当添加/删除/确认报警时,从运行总数中进行添加/减去。根本不需要运行循环来计算事件。

    我会将整个事件移动到sql中。创建一组触发器,在每次添加/删除/确认报警时,从运行总数中进行添加/减去。根本不需要运行循环来计算事件数

    您所说的是哪种类型的集合?在本例中,是ObservableCollection(T),但我相信它继承了collection(T)的大多数方法.你说的是哪种类型的集合?在本例中是ObservableCollection(T),但我相信它继承了集合(T)中的大多数方法。由于这些警报都有一个唯一的id,我开始研究如何在哈希函数中使用它。事实证明,它的实现有点糟糕:add函数在集合中进行了第二次循环,以查找AlarmID>item.AlarmID所在的项。好,那么另一个O(n)。当这个条件被满足时发生了什么?Collection.Insert,它也有O(n)。总之,我没有O(n^2),而是在O(n^2)和O(n^4)之间。。。。去掉了所有的废话,我的速度提高了98%。(从30秒到0.8秒)。这就足够了。稍后我将实现适当的散列。由于这些警报都有一个唯一的id,我开始研究如何在散列函数中使用它。事实证明,它的实现有点糟糕:add函数在集合中进行了第二次循环,以查找AlarmID>item.AlarmID所在的项。好,那么另一个O(n)。当这个条件被满足时发生了什么?Collection.Insert,它也有O(n)。总之,我没有O(n^2),而是在O(n^2)和O(n^4)之间。。。。去掉了所有的废话,我的速度提高了98%。(从30秒到0.8秒)。这就足够了。稍后我将实现适当的散列。我做了一些进一步的测量,结果表明步骤1、2和3并没有花费不合理的时间。但是,更新字段的触发器与SQL count()语句相比如何呢?我做了一些进一步的测量,结果表明步骤1、2和3并没有花费不合理的时间。但是更新字段的触发器与SQL count()语句相比如何呢?