From faa5ba90a3733189978be9400e245520e08ddf18 Mon Sep 17 00:00:00 2001 From: Ahmed Hani <57834677+AhmedHani-dev@users.noreply.github.com> Date: Mon, 26 Sep 2022 13:41:35 +0200 Subject: [PATCH 01/11] Update README.md --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 2bef293..8ba4e8b 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,8 @@ # OptimizeMePlease -## You are probably here because you saw my post on Linkedin. -## Welcome! +### Benchmarks +![image](https://user-images.githubusercontent.com/57834677/192267449-6aca63f8-ea83-4dae-a931-d26c2f90a4b5.png) + # Steps From f8a0d7d3bcefa032a54b79095ad142cd1d71cbc2 Mon Sep 17 00:00:00 2001 From: Ahmed Hani Date: Mon, 26 Sep 2022 13:45:02 +0200 Subject: [PATCH 02/11] Implemented GetAuthors_Optimized Added new dtos --- BenchmarkService.cs | 26 +++++++++++++++++++++++--- OptimizedAuthorDto.cs | 15 +++++++++++++++ OptimizedBookDto.cs | 8 ++++++++ Program.cs | 2 +- 4 files changed, 47 insertions(+), 4 deletions(-) create mode 100644 OptimizedAuthorDto.cs create mode 100644 OptimizedBookDto.cs diff --git a/BenchmarkService.cs b/BenchmarkService.cs index d0a958d..af73b69 100644 --- a/BenchmarkService.cs +++ b/BenchmarkService.cs @@ -3,6 +3,7 @@ using OptimizeMePlease.Context; using System.Collections.Generic; using System.Linq; +using System.Threading.Tasks; namespace OptimizeMePlease { @@ -86,11 +87,30 @@ public List GetAuthors() } [Benchmark] - public List GetAuthors_Optimized() + public async Task> GetAuthors_Optimized() { - List authors = new List(); + using var dbContext = new AppDbContext(); - return authors; + return await dbContext.Authors + .AsNoTracking() + .Where(a => a.Country == "Serbia" && a.Age == 27) + .OrderByDescending(a => a.BooksCount) + .Select(a => new OptimizedAuthorDTO + { + UserFirstName = a.User.FirstName, + UserLastName = a.User.LastName, + UserName = a.User.UserName, + UserEmail = a.User.Email, + AuthorAge = a.Age, + AuthorCountry = a.Country, + AllBooks = a.Books.Where(b => b.Published.Year < 1900).Select(b => new BookDto + { + Name = b.Name, + PublishedYear = b.Published.Year + }).ToList() + }) + .Take(2) + .ToListAsync(); } } } diff --git a/OptimizedAuthorDto.cs b/OptimizedAuthorDto.cs new file mode 100644 index 0000000..05ab209 --- /dev/null +++ b/OptimizedAuthorDto.cs @@ -0,0 +1,15 @@ +using System.Collections.Generic; + +namespace OptimizeMePlease +{ + public class OptimizedAuthorDTO + { + public string UserFirstName { get; set; } + public string UserLastName { get; set; } + public string UserEmail { get; set; } + public string UserName { get; set; } + public int AuthorAge { get; set; } + public string AuthorCountry { get; set; } + public List AllBooks { get; set; } + } +} diff --git a/OptimizedBookDto.cs b/OptimizedBookDto.cs new file mode 100644 index 0000000..c9a3ea3 --- /dev/null +++ b/OptimizedBookDto.cs @@ -0,0 +1,8 @@ +namespace OptimizeMePlease +{ + public class OptimizedBookDto + { + public string Name { get; set; } + public int PublishedYear { get; set; } + } +} diff --git a/Program.cs b/Program.cs index b05ee2d..f5e33b5 100644 --- a/Program.cs +++ b/Program.cs @@ -30,7 +30,7 @@ static void Main(string[] args) //Comment me after first execution, please. //IWillPopulateData(); - //BenchmarkRunner.Run(); + BenchmarkRunner.Run(); } public static void IWillPopulateData() From 3da86090218ec5d8dbf4685204a0e18045020821 Mon Sep 17 00:00:00 2001 From: Ahmed Hani Date: Wed, 28 Sep 2022 13:15:35 +0200 Subject: [PATCH 03/11] Upgraded to .net 6 Moved database context initialization to constructor --- BenchmarkService.cs | 12 ++++++++---- Context/AppDbContext.cs | 2 +- OptimizeMePlease.csproj | 10 +++++----- OptimizeMePlease.sln | 25 +++++++++++++++++++++++++ Program.cs | 3 ++- 5 files changed, 41 insertions(+), 11 deletions(-) create mode 100644 OptimizeMePlease.sln diff --git a/BenchmarkService.cs b/BenchmarkService.cs index af73b69..80bb7e0 100644 --- a/BenchmarkService.cs +++ b/BenchmarkService.cs @@ -10,8 +10,11 @@ namespace OptimizeMePlease [MemoryDiagnoser] public class BenchmarkService { + private readonly AppDbContext _dbContext; + public BenchmarkService() { + _dbContext = new AppDbContext(); } /// @@ -89,11 +92,12 @@ public List GetAuthors() [Benchmark] public async Task> GetAuthors_Optimized() { - using var dbContext = new AppDbContext(); + string authorCountryFilter = "Serbia"; + int authorAgeFilter = 27, authorYearFilter = 1900; - return await dbContext.Authors + return await _dbContext.Authors .AsNoTracking() - .Where(a => a.Country == "Serbia" && a.Age == 27) + .Where(a => a.Country == authorCountryFilter && a.Age == authorAgeFilter) .OrderByDescending(a => a.BooksCount) .Select(a => new OptimizedAuthorDTO { @@ -103,7 +107,7 @@ public async Task> GetAuthors_Optimized() UserEmail = a.User.Email, AuthorAge = a.Age, AuthorCountry = a.Country, - AllBooks = a.Books.Where(b => b.Published.Year < 1900).Select(b => new BookDto + AllBooks = a.Books.Where(b => b.Published.Year < authorYearFilter).Select(b => new BookDto { Name = b.Name, PublishedYear = b.Published.Year diff --git a/Context/AppDbContext.cs b/Context/AppDbContext.cs index a4c4b8b..257ca0a 100644 --- a/Context/AppDbContext.cs +++ b/Context/AppDbContext.cs @@ -7,7 +7,7 @@ public class AppDbContext : DbContext { protected override void OnConfiguring(DbContextOptionsBuilder options) { - options.UseSqlServer("Server=localhost;Database=OptimizeMePlease;Trusted_Connection=True;Integrated Security=true;MultipleActiveResultSets=true"); + options.UseSqlServer("Server=(localdb)\\MSSQLLocalDB;Database=OptimizeMePlease;Trusted_Connection=True;Integrated Security=true;MultipleActiveResultSets=true"); } protected override void OnModelCreating(ModelBuilder modelBuilder) diff --git a/OptimizeMePlease.csproj b/OptimizeMePlease.csproj index 7e4fcc9..c898ab0 100644 --- a/OptimizeMePlease.csproj +++ b/OptimizeMePlease.csproj @@ -2,16 +2,16 @@ Exe - netcoreapp3.1 + net6.0 - - - - + + + + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/OptimizeMePlease.sln b/OptimizeMePlease.sln new file mode 100644 index 0000000..8eb2b0b --- /dev/null +++ b/OptimizeMePlease.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.0.31903.59 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OptimizeMePlease", "OptimizeMePlease.csproj", "{CC059C2B-FDAC-4B94-869B-F139F692624E}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {CC059C2B-FDAC-4B94-869B-F139F692624E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {CC059C2B-FDAC-4B94-869B-F139F692624E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {CC059C2B-FDAC-4B94-869B-F139F692624E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {CC059C2B-FDAC-4B94-869B-F139F692624E}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {74EB4B10-1393-4728-BE1D-06C0FFACD78A} + EndGlobalSection +EndGlobal diff --git a/Program.cs b/Program.cs index f5e33b5..ffaf187 100644 --- a/Program.cs +++ b/Program.cs @@ -2,6 +2,7 @@ using Microsoft.Data.SqlClient; using Microsoft.SqlServer.Management.Common; using Microsoft.SqlServer.Management.Smo; +using OptimizeMePlease.Context; using System; using System.IO; @@ -35,7 +36,7 @@ static void Main(string[] args) public static void IWillPopulateData() { - string sqlConnectionString = @"Server=localhost;Database=OptimizeMePlease;Trusted_Connection=True;Integrated Security=true;MultipleActiveResultSets=true"; + string sqlConnectionString = @"Server=(localdb)\MSSQLLocalDB;Database=OptimizeMePlease;Trusted_Connection=True;Integrated Security=true;MultipleActiveResultSets=true"; string workingDirectory = Environment.CurrentDirectory; string path = Path.Combine(Directory.GetParent(workingDirectory).Parent.Parent.FullName, @"script.sql"); From 80c8a4b186be1ac1aae1da35ae4b45d9bcab86b1 Mon Sep 17 00:00:00 2001 From: Ahmed Hani <57834677+AhmedHani-dev@users.noreply.github.com> Date: Wed, 28 Sep 2022 13:17:11 +0200 Subject: [PATCH 04/11] Updated the benchmark result image --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 8ba4e8b..e265f67 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # OptimizeMePlease -### Benchmarks -![image](https://user-images.githubusercontent.com/57834677/192267449-6aca63f8-ea83-4dae-a931-d26c2f90a4b5.png) +### Benchmark Result +![benchmark](https://user-images.githubusercontent.com/57834677/192765626-174e2c57-f924-4868-b182-857473cef340.PNG) # Steps From 332c90b31e5c96d5a5218f63cc23811384fcd37e Mon Sep 17 00:00:00 2001 From: Ahmed Hani Date: Thu, 29 Sep 2022 01:46:04 +0200 Subject: [PATCH 05/11] Changed books date filter --- BenchmarkService.cs | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/BenchmarkService.cs b/BenchmarkService.cs index 80bb7e0..98f4ea4 100644 --- a/BenchmarkService.cs +++ b/BenchmarkService.cs @@ -1,6 +1,7 @@ using BenchmarkDotNet.Attributes; using Microsoft.EntityFrameworkCore; using OptimizeMePlease.Context; +using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; @@ -10,9 +11,13 @@ namespace OptimizeMePlease [MemoryDiagnoser] public class BenchmarkService { - private readonly AppDbContext _dbContext; - + private AppDbContext _dbContext; public BenchmarkService() + { + } + + [GlobalSetup] + public void GlobalSetup() { _dbContext = new AppDbContext(); } @@ -93,7 +98,8 @@ public List GetAuthors() public async Task> GetAuthors_Optimized() { string authorCountryFilter = "Serbia"; - int authorAgeFilter = 27, authorYearFilter = 1900; + int authorAgeFilter = 27; + DateTime authorDateFilter = new DateTime(1900, 1, 1); return await _dbContext.Authors .AsNoTracking() @@ -107,7 +113,7 @@ public async Task> GetAuthors_Optimized() UserEmail = a.User.Email, AuthorAge = a.Age, AuthorCountry = a.Country, - AllBooks = a.Books.Where(b => b.Published.Year < authorYearFilter).Select(b => new BookDto + AllBooks = a.Books.Where(b => b.Published < authorDateFilter).Select(b => new BookDto { Name = b.Name, PublishedYear = b.Published.Year From 87d51526ee8ab2cc7a2271bcfd1eac6988b42dd8 Mon Sep 17 00:00:00 2001 From: Ahmed Hani Date: Thu, 29 Sep 2022 02:15:50 +0200 Subject: [PATCH 06/11] Used datediff function for date comparison --- BenchmarkService.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/BenchmarkService.cs b/BenchmarkService.cs index 98f4ea4..b9d925e 100644 --- a/BenchmarkService.cs +++ b/BenchmarkService.cs @@ -14,6 +14,7 @@ public class BenchmarkService private AppDbContext _dbContext; public BenchmarkService() { + _dbContext = new AppDbContext(); } [GlobalSetup] @@ -113,7 +114,7 @@ public async Task> GetAuthors_Optimized() UserEmail = a.User.Email, AuthorAge = a.Age, AuthorCountry = a.Country, - AllBooks = a.Books.Where(b => b.Published < authorDateFilter).Select(b => new BookDto + AllBooks = a.Books.Where(b => EF.Functions.DateDiffYear(b.Published, authorDateFilter) > 0).Select(b => new BookDto { Name = b.Name, PublishedYear = b.Published.Year From d7ef488c599d1fef00ee0e732da593abc48d655d Mon Sep 17 00:00:00 2001 From: Ahmed Hani Date: Thu, 29 Sep 2022 02:23:04 +0200 Subject: [PATCH 07/11] Revert back to normal date comparison --- BenchmarkService.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BenchmarkService.cs b/BenchmarkService.cs index b9d925e..20883b5 100644 --- a/BenchmarkService.cs +++ b/BenchmarkService.cs @@ -114,7 +114,7 @@ public async Task> GetAuthors_Optimized() UserEmail = a.User.Email, AuthorAge = a.Age, AuthorCountry = a.Country, - AllBooks = a.Books.Where(b => EF.Functions.DateDiffYear(b.Published, authorDateFilter) > 0).Select(b => new BookDto + AllBooks = a.Books.Where(b => b.Published < authorDateFilter).Select(b => new BookDto { Name = b.Name, PublishedYear = b.Published.Year From 4b2496958a0302d886123fa0089aecf5865c5e8c Mon Sep 17 00:00:00 2001 From: Ahmed Hani Date: Thu, 29 Sep 2022 02:40:13 +0200 Subject: [PATCH 08/11] Move constant authors count number to variable --- BenchmarkService.cs | 4 ++-- Program.cs | 3 +-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/BenchmarkService.cs b/BenchmarkService.cs index 20883b5..3ee050b 100644 --- a/BenchmarkService.cs +++ b/BenchmarkService.cs @@ -99,7 +99,7 @@ public List GetAuthors() public async Task> GetAuthors_Optimized() { string authorCountryFilter = "Serbia"; - int authorAgeFilter = 27; + int authorAgeFilter = 27, authorsCount = 2; DateTime authorDateFilter = new DateTime(1900, 1, 1); return await _dbContext.Authors @@ -120,7 +120,7 @@ public async Task> GetAuthors_Optimized() PublishedYear = b.Published.Year }).ToList() }) - .Take(2) + .Take(authorsCount) .ToListAsync(); } } diff --git a/Program.cs b/Program.cs index ffaf187..6e17ee6 100644 --- a/Program.cs +++ b/Program.cs @@ -2,7 +2,6 @@ using Microsoft.Data.SqlClient; using Microsoft.SqlServer.Management.Common; using Microsoft.SqlServer.Management.Smo; -using OptimizeMePlease.Context; using System; using System.IO; @@ -26,7 +25,7 @@ static void Main(string[] args) { //Debugging BenchmarkService benchmarkService = new BenchmarkService(); - benchmarkService.GetAuthors(); + //benchmarkService.GetAuthors(); //Comment me after first execution, please. //IWillPopulateData(); From 29a2f336da2b7b4130fea9242e7d756c6098dc44 Mon Sep 17 00:00:00 2001 From: Ahmed Hani Date: Thu, 29 Sep 2022 14:01:18 +0200 Subject: [PATCH 09/11] Used the optmized book dto --- BenchmarkService.cs | 32 ++++++++++++-------------------- OptimizedAuthorDto.cs | 12 ++++++------ Program.cs | 3 ++- 3 files changed, 20 insertions(+), 27 deletions(-) diff --git a/BenchmarkService.cs b/BenchmarkService.cs index 3ee050b..725ca15 100644 --- a/BenchmarkService.cs +++ b/BenchmarkService.cs @@ -11,16 +11,8 @@ namespace OptimizeMePlease [MemoryDiagnoser] public class BenchmarkService { - private AppDbContext _dbContext; public BenchmarkService() { - _dbContext = new AppDbContext(); - } - - [GlobalSetup] - public void GlobalSetup() - { - _dbContext = new AppDbContext(); } /// @@ -98,29 +90,29 @@ public List GetAuthors() [Benchmark] public async Task> GetAuthors_Optimized() { - string authorCountryFilter = "Serbia"; - int authorAgeFilter = 27, authorsCount = 2; + using var dbContext = new AppDbContext(); + DateTime authorDateFilter = new DateTime(1900, 1, 1); - return await _dbContext.Authors + return await dbContext.Authors .AsNoTracking() - .Where(a => a.Country == authorCountryFilter && a.Age == authorAgeFilter) + .Where(a => a.Country == "Serbia" && a.Age == 27) .OrderByDescending(a => a.BooksCount) + .Take(2) .Select(a => new OptimizedAuthorDTO { - UserFirstName = a.User.FirstName, - UserLastName = a.User.LastName, + FirstName = a.User.FirstName, + LastName = a.User.LastName, UserName = a.User.UserName, - UserEmail = a.User.Email, - AuthorAge = a.Age, - AuthorCountry = a.Country, - AllBooks = a.Books.Where(b => b.Published < authorDateFilter).Select(b => new BookDto + Email = a.User.Email, + Age = a.Age, + Country = a.Country, + Books = a.Books.Where(b => b.Published < authorDateFilter).Select(b => new OptimizedBookDto { Name = b.Name, PublishedYear = b.Published.Year - }).ToList() + }) }) - .Take(authorsCount) .ToListAsync(); } } diff --git a/OptimizedAuthorDto.cs b/OptimizedAuthorDto.cs index 05ab209..21edd0b 100644 --- a/OptimizedAuthorDto.cs +++ b/OptimizedAuthorDto.cs @@ -4,12 +4,12 @@ namespace OptimizeMePlease { public class OptimizedAuthorDTO { - public string UserFirstName { get; set; } - public string UserLastName { get; set; } - public string UserEmail { get; set; } + public string FirstName { get; set; } + public string LastName { get; set; } + public string Email { get; set; } public string UserName { get; set; } - public int AuthorAge { get; set; } - public string AuthorCountry { get; set; } - public List AllBooks { get; set; } + public int Age { get; set; } + public string Country { get; set; } + public IEnumerable Books { get; set; } } } diff --git a/Program.cs b/Program.cs index 6e17ee6..4d6d05e 100644 --- a/Program.cs +++ b/Program.cs @@ -24,8 +24,9 @@ public class Program static void Main(string[] args) { //Debugging - BenchmarkService benchmarkService = new BenchmarkService(); + //BenchmarkService benchmarkService = new BenchmarkService(); //benchmarkService.GetAuthors(); + //var authors = benchmarkService.GetAuthors_Optimized().Result; //Comment me after first execution, please. //IWillPopulateData(); From cc7ac90645c1eb9ab80bc8df97e74b7819ee73c4 Mon Sep 17 00:00:00 2001 From: Ahmed Hani Date: Mon, 3 Oct 2022 21:51:27 +0200 Subject: [PATCH 10/11] Changed function to sync --- BenchmarkService.cs | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/BenchmarkService.cs b/BenchmarkService.cs index 725ca15..acad45e 100644 --- a/BenchmarkService.cs +++ b/BenchmarkService.cs @@ -88,32 +88,32 @@ public List GetAuthors() } [Benchmark] - public async Task> GetAuthors_Optimized() + public List GetAuthors_Optimized() { using var dbContext = new AppDbContext(); DateTime authorDateFilter = new DateTime(1900, 1, 1); - return await dbContext.Authors - .AsNoTracking() - .Where(a => a.Country == "Serbia" && a.Age == 27) - .OrderByDescending(a => a.BooksCount) - .Take(2) - .Select(a => new OptimizedAuthorDTO + return dbContext.Authors + .AsNoTracking() + .Where(a => a.Country == "Serbia" && a.Age == 27) + .OrderByDescending(a => a.BooksCount) + .Take(2) + .Select(a => new OptimizedAuthorDTO + { + FirstName = a.User.FirstName, + LastName = a.User.LastName, + UserName = a.User.UserName, + Email = a.User.Email, + Age = a.Age, + Country = a.Country, + Books = a.Books.Where(b => b.Published < authorDateFilter).Select(b => new OptimizedBookDto { - FirstName = a.User.FirstName, - LastName = a.User.LastName, - UserName = a.User.UserName, - Email = a.User.Email, - Age = a.Age, - Country = a.Country, - Books = a.Books.Where(b => b.Published < authorDateFilter).Select(b => new OptimizedBookDto - { - Name = b.Name, - PublishedYear = b.Published.Year - }) + Name = b.Name, + PublishedYear = b.Published.Year }) - .ToListAsync(); + }) + .ToList(); } } } From 24fbf8d33f42d54ee850f65bd3b7b66e1b8ca7b1 Mon Sep 17 00:00:00 2001 From: Ahmed Hani Date: Mon, 3 Oct 2022 22:07:46 +0200 Subject: [PATCH 11/11] Changed books filter to datepart (with year) --- BenchmarkService.cs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/BenchmarkService.cs b/BenchmarkService.cs index acad45e..f0a1132 100644 --- a/BenchmarkService.cs +++ b/BenchmarkService.cs @@ -1,10 +1,8 @@ using BenchmarkDotNet.Attributes; using Microsoft.EntityFrameworkCore; using OptimizeMePlease.Context; -using System; using System.Collections.Generic; using System.Linq; -using System.Threading.Tasks; namespace OptimizeMePlease { @@ -92,8 +90,6 @@ public List GetAuthors_Optimized() { using var dbContext = new AppDbContext(); - DateTime authorDateFilter = new DateTime(1900, 1, 1); - return dbContext.Authors .AsNoTracking() .Where(a => a.Country == "Serbia" && a.Age == 27) @@ -107,7 +103,7 @@ public List GetAuthors_Optimized() Email = a.User.Email, Age = a.Age, Country = a.Country, - Books = a.Books.Where(b => b.Published < authorDateFilter).Select(b => new OptimizedBookDto + Books = a.Books.Where(b => b.Published.Year < 1900).Select(b => new OptimizedBookDto { Name = b.Name, PublishedYear = b.Published.Year