简体   繁体   English

是字典 <TKey, TValue> 比列表上的LINQ更快 <T> ?

[英]Is Dictionary<TKey, TValue> faster than LINQ on a List<T>?

I generally use List<T> for collections. 我通常使用List<T>来收集。 But if I need a fast lookup on a collection, then eg in the following example I would use a Dictionary so I could look it up quickly by id : 但是如果我需要对集​​合进行快速查找,那么例如在下面的示例中我将使用一个字典,以便我可以通过id快速查找它:

Dictionary<int, Customer>

But since I can use LINQ to query the List<T> anyway, as below, is there any reason to go through the trouble of using a Dictionary instead of a List? 但是既然我可以使用LINQ来查询List<T> ,如下所示,有没有理由遇到使用Dictionary而不是List的麻烦? Is Dictionary faster or is LINQ doing something behind the scenes that makes it just as fast? 字典更快还是LINQ在幕后做一些让它同样快的东西?

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            List<Customer> customers = new List<Customer>()
            {
             new Customer { Id = 234, FirstName = "Jim", LastName = "Smith" },
             new Customer { Id = 345, FirstName = "John", LastName = "Thomas" },
             new Customer { Id = 654, FirstName = "Rick", LastName = "Ashton" },
             new Customer { Id = 948, FirstName = "Rod", LastName = "Anders" }
            };

            var customer = (from c in customers
                           where c.Id == 654 select c).SingleOrDefault();
            Console.WriteLine(customer.Display());

            Console.ReadLine();

        }
    }


    public class Customer
    {
        public int Id { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }

        internal string Display()
        {
            return String.Format("{0}, {1} ({2})", LastName, FirstName, Id);
        }

    }
}

If you logically want to create a collection where you can easily look up a customer by their ID, I would use some form of IDictionary<int, Customer> . 如果您在逻辑上想要创建一个集合,您可以通过其ID轻松查找客户,我将使用某种形式的IDictionary<int, Customer> That expresses what you're trying to achieve. 这表达了你想要实现的目标。

Now you could use a list to do the same thing, and as leppie says for small datasets it will be about as fast or even faster - but for small datasets it'll be very fast anyway, so why do you care? 现在你可以使用一个列表来做同样的事情,正如leppie所说的那样,对于小型数据集来说它会快得多,甚至更快 - 但是对于小型数据集来说它无论如何都会非常快,所以你为什么要关心? I think it's more important to tell the reader of your code what you're trying to do with the collection - and a dictionary achieves that aim far more effectively than a list, IMO. 我认为告诉读者你的代码你正在尝试用这个集合做什么更重要 - 而字典实现这个目标远比列表IMO更有效。

LINQ isn't magic. LINQ不是魔术。 It will still have to iterate through a list to find the element you want. 它仍然需要遍历列表才能找到所需的元素。 Dictionary will still be faster (for collections of suitable size, as leppie points out) 字典仍然会更快(对于合适大小的集合,正如leppie指出的那样)

According to MSDN getting an item from a dictionary based on key "approaches an O(1) operation." 根据MSDN从字典中获取基于关键字“接近O(1)操作”的项目。 On the other hand executing Where on a list loops through the elements to find matches. 另一方面,执行列表中的Where循环遍历元素以查找匹配项。 So generally dictionary will be definitely faster. 所以一般字典肯定会更快。

If you want to speed up Linq operations you can use Indexed LINQ which allows to put indexes on your collections. 如果你想加速Linq操作,你可以使用Indexed LINQ ,它允许在你的集合上放置索引。

对于小于20个项目的列表, Dictionary/Hashtable的开销将导致它比列表慢。

LINQ will generally be slower in this sort of operation. LINQ在这种操作中通常会较慢。 However, on a small enough set (such as your example), it'll likely be faster, due to the differences in overhead. 但是,在足够小的集合(例如您的示例)上,由于开销的差异,它可能会更快。 However again, on a small enough set (such as your example) the difference between either solution is going to be so small that it won't matter as much as the question of whether dictionary look up or Where() reads more naturally. 然而,再一次,在一个足够小的集合(例如你的例子)中,任何一个解决方案之间的差异将会非常小,以至于字典查找或Where()是否更自然地读取的问题无关紧要。

您可以在此集合中使用SortedList并执行二进制搜索(考虑到它在第一次比较后消除了一半的集合)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM