1. 程式人生 > >EF6學習筆記十七:快照追蹤與代理追蹤性能測試

EF6學習筆記十七:快照追蹤與代理追蹤性能測試

ble src play nbsp png 它的 close 延遲加載 tar

要專業系統地學習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只是用於導航屬性的延遲加載,如果我們想用代理式變更追蹤,除非真正的理解它的問題並有一個合理的理由去使用它,當然這也就意味著,當用快照式變更追蹤遇到性能瓶頸時,可以考慮使用代理式變更追蹤(大部分情況下還是不會)”

EF6學習筆記十七:快照追蹤與代理追蹤性能測試