public static void Benchmark1(int total_parents, List <long> testTimes, List <long> testTimes2, ref int rowcount, ref int rowcount2) { var watch = new System.Diagnostics.Stopwatch(); watch.Start(); using (var ctx = new CodexMicroORMTestEntities()) { for (int parentcnt = 1; parentcnt <= total_parents; ++parentcnt) { var parent = new Person() { Name = $"NP{parentcnt}", Age = (parentcnt % 60) + 20, Gender = (parentcnt % 2) == 0 ? "F" : "M", LastUpdatedBy = Environment.UserName, LastUpdatedDate = DateTime.UtcNow }; parent.Phones.Add(new Phone() { Number = "888-7777", PhoneTypeID = PhoneTypeEnum.Mobile, LastUpdatedBy = Environment.UserName, LastUpdatedDate = DateTime.UtcNow }); parent.Phones.Add(new Phone() { Number = "777-6666", PhoneTypeID = PhoneTypeEnum.Work, LastUpdatedBy = Environment.UserName, LastUpdatedDate = DateTime.UtcNow }); if ((parentcnt % 12) == 0) { ctx.Phones.Add(new Phone() { Number = "666-5555", PhoneTypeID = PhoneTypeEnum.Home, LastUpdatedBy = Environment.UserName, LastUpdatedDate = DateTime.UtcNow }); } else { parent.Phones.Add(new Phone() { Number = "777-6666", PhoneTypeID = PhoneTypeEnum.Home, LastUpdatedBy = Environment.UserName, LastUpdatedDate = DateTime.UtcNow }); } rowcount += 4; for (int childcnt = 1; childcnt <= (parentcnt % 4); ++childcnt) { var child = new Person() { Name = $"NC{parentcnt}{childcnt}", Age = parent.Age - 20, Gender = (parentcnt % 2) == 0 ? "F" : "M", LastUpdatedBy = Environment.UserName, LastUpdatedDate = DateTime.UtcNow, Phones = new Phone[] { new Phone() { Number = "999-8888", PhoneTypeID = PhoneTypeEnum.Mobile, LastUpdatedBy = Environment.UserName, LastUpdatedDate = DateTime.UtcNow } } }; parent.Kids.Add(child); rowcount += 2; } ctx.People.Add(parent); } ctx.SaveChanges(); } testTimes.Add(watch.ElapsedMilliseconds); watch.Restart(); // For purposes of benchmarking, treat this as a completely separate operation using (var ctx = new CodexMicroORMTestEntities()) { // For everyone who's a parent of at least 30 yo, if at least 2 children of same sex, remove work phone, increment age var list = (from p in ctx.People where p.Age >= 30 from c in p.Kids group c by new { Person = p, c.Gender } into g where g.Count() > 1 select g.Key.Person); foreach (var p in list) { p.Age += 1; p.LastUpdatedDate = DateTime.UtcNow; p.LastUpdatedBy = Environment.UserName; var toDelete = (from a in p.Phones where a.PhoneTypeID == PhoneTypeEnum.Work select a).FirstOrDefault(); if (toDelete != null) { ctx.Entry(toDelete).State = EntityState.Deleted; } } rowcount2 += ctx.SaveChanges(); } watch.Stop(); testTimes2.Add(watch.ElapsedMilliseconds); }
public static void Benchmark3SavePer(int total_parents, List <long> testTimes, List <long> testTimes2, ref int rowcount, ref int rowcount2) { var watch = new System.Diagnostics.Stopwatch(); watch.Start(); // Attempted parallelization gives "New transaction is not allowed because there are other threads running in the session." deep inside EF for (int parentcnt = 1; parentcnt <= total_parents; ++parentcnt) { using (var ctx = new CodexMicroORMTestEntities()) { var parent = new Person() { Name = $"NP{parentcnt}", Age = (parentcnt % 60) + 20, Gender = (parentcnt % 2) == 0 ? "F" : "M", LastUpdatedBy = Environment.UserName, LastUpdatedDate = DateTime.UtcNow }; parent.Phones.Add(new Phone() { Number = "888-7777", PhoneTypeID = PhoneTypeEnum.Mobile, LastUpdatedBy = Environment.UserName, LastUpdatedDate = DateTime.UtcNow }); parent.Phones.Add(new Phone() { Number = "777-6666", PhoneTypeID = PhoneTypeEnum.Work, LastUpdatedBy = Environment.UserName, LastUpdatedDate = DateTime.UtcNow }); if ((parentcnt % 12) == 0) { ctx.Phones.Add(new Phone() { Number = "666-5555", PhoneTypeID = PhoneTypeEnum.Home, LastUpdatedBy = Environment.UserName, LastUpdatedDate = DateTime.UtcNow }); } else { parent.Phones.Add(new Phone() { Number = "777-6666", PhoneTypeID = PhoneTypeEnum.Home, LastUpdatedBy = Environment.UserName, LastUpdatedDate = DateTime.UtcNow }); } rowcount += 4; for (int childcnt = 1; childcnt <= (parentcnt % 4); ++childcnt) { var child = new Person() { Name = $"NC{parentcnt}{childcnt}", Age = parent.Age - 20, Gender = (parentcnt % 2) == 0 ? "F" : "M", LastUpdatedBy = Environment.UserName, LastUpdatedDate = DateTime.UtcNow, Phones = new Phone[] { new Phone() { Number = "999-8888", PhoneTypeID = PhoneTypeEnum.Mobile, LastUpdatedBy = Environment.UserName, LastUpdatedDate = DateTime.UtcNow } } }; parent.Kids.Add(child); rowcount += 2; } ctx.People.Add(parent); ctx.SaveChanges(); } } testTimes.Add(watch.ElapsedMilliseconds); watch.Restart(); // For purposes of benchmarking, treat this as a completely separate operation using (var ctx = new CodexMicroORMTestEntities()) { int?id = null; // For everyone who's a parent of at least 30 yo, if at least 2 children of same sex, remove work phone, increment age // Note: ToList required or can lead to errors on save var list = (from p in ctx.People where p.Age >= 30 from c in p.Kids group c by new { Person = p, c.Gender } into g where g.Count() > 1 select g.Key.Person).ToList(); // Attempted parallelization gives "Object reference not set to an instance of an object." deep inside EF foreach (var p in list) { if (!id.HasValue) { id = p.PersonID; } p.Age += 1; p.LastUpdatedDate = DateTime.UtcNow; p.LastUpdatedBy = Environment.UserName; var toDelete = (from a in p.Phones where a.PhoneTypeID == PhoneTypeEnum.Work select a).FirstOrDefault(); if (toDelete != null) { ctx.Entry(toDelete).State = EntityState.Deleted; } rowcount2 += ctx.SaveChanges(); } // Simulate "later heavy read access"... for (int c = 0; c < 50000; ++c) { var work = (from p in list where p.PersonID == c + id.GetValueOrDefault() from ph in p.Phones where ph.PhoneTypeID == PhoneTypeEnum.Work select ph).FirstOrDefault(); if (work != null && work.Number == "123") { MessageBox.Show("Found (should never!)"); } } } rowcount2 += 50000; watch.Stop(); testTimes2.Add(watch.ElapsedMilliseconds); }