zoukankan      html  css  js  c++  java
  • EF6学习笔记十七:快照追踪与代理追踪性能测试

    要专业系统地学习EF推荐《你必须掌握的Entity Framework 6.x与Core 2.0》。这本书作者(汪鹏,Jeffcky)的博客:https://www.cnblogs.com/CreateMyself/

     上一篇我们知道了快照和代理怎么回事,所以来测试看看

    测试添加操作,插入一千条数据看看

    快照五次,时间分别为:  1335ms 635ms  1025ms 1242ms 717ms

    //快照插入一千条数据
    var watch = new Stopwatch();
    watch.Start();
    
    List<Book> books = new List<Book>();
    for (int i = 0; i < 1000; i++)
    {
        books.Add(new Book { Name = $"book{i + 1}", PageSize = 1000 + i, AddTime = DateTime.Now });
    }
    ctx.Books.AddRange(books);
    ctx.SaveChanges();
    
    watch.Stop();
    Console.WriteLine(watch.ElapsedMilliseconds);  
    View Code

    代理添加,时间分别为:  1287ms 701ms 1460ms 1289ms 968ms

    //  代理插入一千条数据
    ctx.Configuration.AutoDetectChangesEnabled = false;
    var watch = new Stopwatch();
    watch.Start();
    ctx.Database.Log = Console.WriteLine;
    List<Book> books = new List<Book>();
    for (int i = 0; i < 3000; i++)
    {
        books.Add(new Book { Name = $"book{i + 1}", PageSize = 1000 + i, AddTime = DateTime.Now });
    }
    ctx.Books.AddRange(books);
    ctx.SaveChanges();
    
    watch.Stop();
    Console.WriteLine(watch.ElapsedMilliseconds);
    View Code

    有一个问题,添加一千条数据,EF是逐条添加的,但是顺序为什么不对呢?

    再来看看修改数据,我们对三千条数据进行修改

    快照追踪方式,我记录了两组数据

    1、1692ms  518ms 474ms 561ms 519ms  为什么这后面的几个同时这么短?那是因为我没有改代码,继续执行修改,那么其实虽然说给属性赋值了,但并没有修改,EF也不会去执行

    2、3303ms  2724ms 2250ms 2796ms  现在我就将每一次修改的数据进行改变

    var watch = new Stopwatch();
    watch.Start();
    
    var books = ctx.Books.ToList();
    books.ForEach(book =>
    {
        book.Name = "book";
        book.PageSize = 999;
        book.AddTime = new DateTime(1999, 9, 9);
    });
    ctx.SaveChanges();
    
    watch.Stop();
    Console.WriteLine(watch.ElapsedMilliseconds);
    View Code

     代理方式,现在就有差距了,会比快照耗时一些

    1、3010ms 3144ms 1851ms 2989ms

    2、1788ms 3006ms 2738ms 1681ms

    ctx.Configuration.AutoDetectChangesEnabled = false;
    var watch = new Stopwatch();
    watch.Start();
    
    var books = ctx.Books.ToList();
    books.ForEach(book =>
    {
        book.Name = "book2";
        book.PageSize = 888;
        book.AddTime = new DateTime(1999, 9, 9);
    });
    ctx.SaveChanges();
    
    watch.Stop();
    Console.WriteLine(watch.ElapsedMilliseconds);
    View Code

     如果说我们只是修改三千条数据中的其中三条呢?

    快照追踪

    643ms 424ms 609ms 575ms

    var watch = new Stopwatch();
    watch.Start();
    
    var books = ctx.Books.ToList();
    books.ForEach(book =>
    {
        if (book.PageSize < 1003)
        {
            book.Name = "book2";
            book.PageSize = 777;
            book.AddTime = new DateTime(1999, 9, 9);
        }
    });
    ctx.SaveChanges();
    watch.Stop();
    Console.WriteLine(watch.ElapsedMilliseconds);
    View Code

    现在我们把三条之外的两千多条实体的属性也赋值,但是还是原来的值

    1838ms 1291ms 2992ms 3175ms

    var watch = new Stopwatch();
    watch.Start();
    
    var books = ctx.Books.ToList();
    books.ForEach(book =>
    {
        if (book.PageSize < 1003)
        {
            book.Name = "book2";
            book.PageSize = 777;
            book.AddTime = new DateTime(1999, 9, 9);
        }
        else
        {
            book.Name = book.Name;
            book.PageSize = book.PageSize;
            book.AddTime = book.AddTime;
        }
    });
    ctx.SaveChanges();
    watch.Stop();
    Console.WriteLine(watch.ElapsedMilliseconds);
    View Code

     代理追踪

    584ms 513ms 492ms

    var watch = new Stopwatch();
    watch.Start();
    ctx.Configuration.AutoDetectChangesEnabled = fal
    var books = ctx.Books.ToList();
    books.ForEach(book =>
    {
        if (book.PageSize < 1003)
        {
            book.Name = "book";
            book.PageSize = 888;
            book.AddTime = new DateTime(1999, 9, 9);
        }
    });
    ctx.SaveChanges();
    watch.Stop();
    Console.WriteLine(watch.ElapsedMilliseconds);
    View Code

    3247ms 2481ms 3051ms

    var watch = new Stopwatch();
    watch.Start();
    ctx.Configuration.AutoDetectChangesEnabled = f
    var books = ctx.Books.ToList();
    books.ForEach(book =>
    {
        if (book.PageSize < 1003)
        {
            book.Name = "book";
            book.PageSize = 888;
            book.AddTime = new DateTime(1999, 9, 9);
        }
        else
        {
            book.Name = book.Name;
            book.PageSize = book.PageSize;
            book.AddTime = book.AddTime;
        }
    });
    ctx.SaveChanges();
    watch.Stop();
    Console.WriteLine(watch.ElapsedMilliseconds);
    View Code

    感觉没什么变化,可能是我的数据太少了

    最后引用作者的一段话:

    “对于代理变更追踪,笔者认为似乎没有什么可用之处,几乎没看见过将属性标记为virtual作为代理类来用,再者EF团队在代理式变更追踪方面并没有过多投入,二者的性能比较就当做了解。

    virtual只是用于导航属性的延迟加载,如果我们想用代理式变更追踪,除非真正的理解它的问题并有一个合理的理由去使用它,当然这也就意味着,当用快照式变更追踪遇到性能瓶颈时,可以考虑使用代理式变更追踪(大部分情况下还是不会)” 

  • 相关阅读:
    子类继承方法的重写
    操作系统的用户模式和内核模式
    Java中的CAS
    FaceBook SDK登录功能实现(Eclipse)
    eclipse集成ijkplayer项目
    android handler传递数据
    android发送短信
    hadoop中的job.setOutputKeyClass与job.setMapOutputKeyClass
    mysql对事务的支持
    使用jd-gui+javassist修改已编译好的class文件
  • 原文地址:https://www.cnblogs.com/jinshan-go/p/10303088.html
Copyright © 2011-2022 走看看