c# - LINQ 到排序列表

标签 c# linq sortedlist sorteddictionary

我是一个完整的 LINQ 新手,所以我不知道我的 LINQ 是否不适合我需要做的事情,或者我对性能的期望是否过高。

我有一个对象的 SortedList,由 int 键控; SortedList 而不是 SortedDictionary,因为我将使用预先排序的数据填充集合。我的任务是找到确切的 key ,或者如果没有确切的 key ,则找到具有下一个更高值的 key 。如果搜索对于列表而言太高(例如最高键是 100,但搜索 105),则返回 null。

// The structure of this class is unimportant.  Just using
// it as an illustration.
public class CX
{
    public int KEY;
    public DateTime DT;
}

static CX getItem(int i, SortedList<int, CX> list)
{
    var items =
    (from kv in list
     where kv.Key >= i
     select kv.Key);

    if (items.Any())
    {
        return list[items.Min()];
    }

    return null;
}

给定一个包含 50,000 条记录的列表,调用 getItem 500 次大约需要 1.5 秒。调用它 50,000 次需要超过 2 分钟。这个性能看起来很差。我的 LINQ 不好吗?我期待太多了吗?我应该推出自己的二进制搜索功能吗?

最佳答案

首先,您的查询将被评估两次(一次针对 Any,一次针对 Min)。其次,Min 要求它遍历整个列表,即使它已排序这一事实意味着第一项将是最小值。你应该能够改变这个:

if (items.Any())
{
    return list[items.Min()];
}

对此:

var default = 
    (from kv in list
     where kv.Key >= i
     select (int?)kv.Key).FirstOrDefault();

if(default != null) return list[default.Value];

return null;

更新

因为您选择的是值类型,FirstOrDefault 不会返回可为 null 的对象。我已更改您的查询以将所选值转换为 int?,从而允许检查结果值是否为 null。我会提倡使用 ContainsKey,因为如果您的列表包含 0 的值,它将返回 true。例如,假设您有以下值

0 2 4 6 8

如果您要传递小于或等于 8 的任何值,那么您将获得正确的值。但是,如果您传入 9,您将得到 0 (default(int)),它列表中,但不在 一个有效的结果。

关于c# - LINQ 到排序列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2897749/

相关文章:

c# - List<T> OrderBy 字母顺序

c# - XSD 数据集与 Oracle 数据库

c# - 使自定义类可用于 LINQ 查询

c# - SortedList<> 及其奇怪的 setter

c# - 为什么排序字典和列表的添加、删除和获取值比未排序慢?

c# - 重新排序集合 C#

c# - 如何获取密码 html 帮助程序以在验证失败时呈现密码

c# - SelectCommand.Connection 属性尚未初始化。数据库

c# - 如何在列表中列出具有不为空的字段的元素编号?

linq - MonoDroid、SQLite 和 LINQ