为什么字典比列表快得多? [英] Why is dictionary so much faster than list?

查看:220
本文介绍了为什么字典比列表快得多?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在测试从Dictionary VS列表获取数据的速度。

我已使用以下代码进行测试:

I am testing the speed of getting data from Dictionary VS list.
I've used this code to test :

    internal class Program
{
    private static void Main(string[] args)
    {
        var stopwatch = new Stopwatch();
        List<Grade> grades = Grade.GetData().ToList();
        List<Student> students = Student.GetStudents().ToList();

        stopwatch.Start();
        foreach (Student student in students)
        {
            student.Grade = grades.Single(x => x.StudentId == student.Id).Value;
        }
        stopwatch.Stop();
        Console.WriteLine("Using list {0}", stopwatch.Elapsed);
        stopwatch.Reset();
        students = Student.GetStudents().ToList();
        stopwatch.Start();
        Dictionary<Guid, string> dic = Grade.GetData().ToDictionary(x => x.StudentId, x => x.Value);
        foreach (Student student in students)
        {
            student.Grade = dic[student.Id];
        }
        stopwatch.Stop();
        Console.WriteLine("Using dictionary {0}", stopwatch.Elapsed);
        Console.ReadKey();
    }
}

public class GuidHelper
{
    public static List<Guid> ListOfIds=new List<Guid>();

    static GuidHelper()
    {
        for (int i = 0; i < 10000; i++)
        {
            ListOfIds.Add(Guid.NewGuid());
        }
    }
}


public class Grade
{
    public Guid StudentId { get; set; }
    public string Value { get; set; }

    public static IEnumerable<Grade> GetData()
    {
        for (int i = 0; i < 10000; i++)
        {
            yield return new Grade
                             {
                                 StudentId = GuidHelper.ListOfIds[i], Value = "Value " + i
                             };
        }
    }
}

public class Student
{
    public Guid Id { get; set; }
    public string Name { get; set; }
    public string Grade { get; set; }

    public static IEnumerable<Student> GetStudents()
    {
        for (int i = 0; i < 10000; i++)
        {
            yield return new Student
                             {
                                 Id = GuidHelper.ListOfIds[i],
                                 Name = "Name " + i
                             };
        }
    }
}

有学生名单和在记忆成绩方面,他们有共同的StudentId。

第一种方法是尝试在机器上花费将近7秒的时间在列表上使用LINQ查找学生的成绩,另一种方法是先将List转换为字典,然后使用键从字典中查找学生的成绩不到一秒钟的时间。

There is list of students and grades in memory they have StudentId in common.
In first way I tried to find Grade of a student using LINQ on a list that takes near 7 seconds on my machine and in another way first I converted List into dictionary then finding grades of student from dictionary using key that takes less than a second .

推荐答案

执行此操作时:

student.Grade = grades.Single(x => x.StudentId == student.Id).Value;

如所写,它必须枚举整个 List ,直到在列表中找到具有正确的StudentId的条目(条目0是否匹配lambda?否...条目1是否匹配lambda?否...等等)。这是O(n)。既然您对每个学生都做一次,那么它就是O(n ^ 2)。

As written it has to enumerate the entire List until it finds the entry in the List that has the correct studentId (does entry 0 match the lambda? No... Does entry 1 match the lambda? No... etc etc). This is O(n). Since you do it once for every student, it is O(n^2).

但是什么时候这样做:

student.Grade = dic [student.Id];

如果要查找某个通过按字典中的元素,它可以立即跳到字典中的位置-这是O(1)。为每个学生做的O(n)。 (如果您想知道这是怎么做的,Dictionary会对键进行数学运算,将其转换为一个值,该值在Dictionary内的位置,与插入键时的位置相同)

If you want to find a certain element by key in a dictionary, it can instantly jump to where it is in the dictionary - this is O(1). O(n) for doing it for every student. (If you want to know how this is done - Dictionary runs a mathematical operation on the key, which turns it into a value that is a place inside the dictionary, which is the same place it put it when it was inserted)

因此,字典速度更快,因为您使用了更好的算法。

So, dictionary is faster because you used a better algorithm.

这篇关于为什么字典比列表快得多?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆