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  现在我就将每一次修改的数据进行改变

扫描二维码关注公众号,回复: 5020914 查看本文章
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只是用于导航属性的延迟加载,如果我们想用代理式变更追踪,除非真正的理解它的问题并有一个合理的理由去使用它,当然这也就意味着,当用快照式变更追踪遇到性能瓶颈时,可以考虑使用代理式变更追踪(大部分情况下还是不会)” 

猜你喜欢

转载自www.cnblogs.com/jinshan-go/p/10303088.html
EF6