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>();View Codefor (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);
代理添加,時間分別為: 1287ms 701ms 1460ms 1289ms 968ms
// 代理插入一千條數據View Codectx.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);
有一個問題,添加一千條數據,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學習筆記十七:快照追蹤與代理追蹤性能測試