diff --git a/collections-lists/SortListByProperty/SortListByProperty/Book.cs b/collections-lists/SortListByProperty/SortListByProperty/Book.cs index 8ff0d6b2ab..90dc8eed38 100644 --- a/collections-lists/SortListByProperty/SortListByProperty/Book.cs +++ b/collections-lists/SortListByProperty/SortListByProperty/Book.cs @@ -1,22 +1,21 @@ -namespace SortListByProperty +namespace SortListByProperty; + +public class Book : IComparable { - public class Book : IComparable - { - public string Title { get; set; } - public string Author { get; set; } - public int Pages { get; set; } + public required string Title { get; set; } + public required string Author { get; set; } + public int Pages { get; set; } - public int CompareTo(Book other) - { - if (other == null) - return 1; + public int CompareTo(Book? other) + { + if (other == null) + return 1; - if (this.Pages > other.Pages) - return 1; - else if (this.Pages < other.Pages) - return -1; - else - return 0; - } + if (this.Pages > other.Pages) + return 1; + else if (this.Pages < other.Pages) + return -1; + else + return 0; } } diff --git a/collections-lists/SortListByProperty/SortListByProperty/DataGenerator.cs b/collections-lists/SortListByProperty/SortListByProperty/DataGenerator.cs index e713915470..60c5bb77ed 100644 --- a/collections-lists/SortListByProperty/SortListByProperty/DataGenerator.cs +++ b/collections-lists/SortListByProperty/SortListByProperty/DataGenerator.cs @@ -1,28 +1,25 @@ -using System.Text; +using System.Text; -namespace SortListByProperty +namespace SortListByProperty; + +public static class DataGenerator { - public static class DataGenerator + public static int GenerateNumber(int min, int max) { - private static readonly Random _random = new Random(); + return Random.Shared.Next(min, max); + } - public static int GenerateNumber(int min, int max) - { - return _random.Next(min, max); - } + public static string GenerateString(int size) + { + var builder = new StringBuilder(size); + char start = 'a'; - public static string GenerateString(int size) + for (int i = 0; i < size; i++) { - var builder = new StringBuilder(size); - char start = 'a'; - - for (int i = 0; i < size; i++) - { - var text = (char)_random.Next(start, start + 26); - builder.Append(text); - } - - return builder.ToString(); + var text = (char)Random.Shared.Next(start, start + 26); + builder.Append(text); } + + return builder.ToString(); } } diff --git a/collections-lists/SortListByProperty/SortListByProperty/Program.cs b/collections-lists/SortListByProperty/SortListByProperty/Program.cs index 7f9d52f048..15a145e9ea 100644 --- a/collections-lists/SortListByProperty/SortListByProperty/Program.cs +++ b/collections-lists/SortListByProperty/SortListByProperty/Program.cs @@ -1,4 +1,4 @@ -using BenchmarkDotNet.Running; +using BenchmarkDotNet.Running; using SortListByProperty; -var benchmark = BenchmarkRunner.Run(); \ No newline at end of file +BenchmarkRunner.Run(); diff --git a/collections-lists/SortListByProperty/SortListByProperty/Sort.cs b/collections-lists/SortListByProperty/SortListByProperty/Sort.cs index c5694fae44..11dceae3ac 100644 --- a/collections-lists/SortListByProperty/SortListByProperty/Sort.cs +++ b/collections-lists/SortListByProperty/SortListByProperty/Sort.cs @@ -1,69 +1,24 @@ -using BenchmarkDotNet.Attributes; +namespace SortListByProperty; -namespace SortListByProperty +public class Sort { - public class Sort + public List SortByTitleUsingLinq(List originalList) { - [ArgumentsSource(nameof(GenerateBooks))] - [Benchmark] - public List SortByTitleUsingLinq(List originalList) - { - return originalList.OrderBy(x => x.Title).ToList(); - } - - public List SortByAuthorAndPagesUsingLinq(List originalList) - { - return originalList.OrderBy(x => x.Author).ThenBy(x => x.Pages).ToList(); - } - - [ArgumentsSource(nameof(GenerateBooks))] - [Benchmark] - public void SortByTitleIComparable(List originalList) - { - originalList.Sort(); - } - - [ArgumentsSource(nameof(GenerateBooks))] - [Benchmark] - public void SortByTitleIComparer(List originalList) - { - originalList.Sort(new SortBookByTitle()); - } - - [ArgumentsSource(nameof(GenerateBooks))] - [Benchmark] - public void SortByTitleComparisonDelegate(List originalList) - { - var comparer = new Comparison(Sort.CompareBooks); - - originalList.Sort(comparer); - } - - public static int CompareBooks(Book x, Book y) - { - return x.Title.CompareTo(y.Title); - } - - public IEnumerable> GenerateBooks() - { - var data = new List>(); - var books = new List(); - - for (int i = 0; i < 1000; i++) - { - var book = new Book - { - Title = DataGenerator.GenerateString(10), - Author = DataGenerator.GenerateString(15), - Pages = DataGenerator.GenerateNumber(100, 1000) - }; + return originalList.OrderBy(x => x.Title).ToList(); + } - books.Add(book); - } + public List SortByAuthorAndPagesUsingLinq(List originalList) + { + return originalList.OrderBy(x => x.Author).ThenBy(x => x.Pages).ToList(); + } - data.Add(books); + public List SortByPagesDescendingUsingLinq(List originalList) + { + return originalList.OrderByDescending(x => x.Pages).ToList(); + } - return data; - } + public static int CompareBooks(Book x, Book y) + { + return x.Title.CompareTo(y.Title); } } diff --git a/collections-lists/SortListByProperty/SortListByProperty/SortBenchmarks.cs b/collections-lists/SortListByProperty/SortListByProperty/SortBenchmarks.cs new file mode 100644 index 0000000000..ce7f13d324 --- /dev/null +++ b/collections-lists/SortListByProperty/SortListByProperty/SortBenchmarks.cs @@ -0,0 +1,83 @@ +using BenchmarkDotNet.Attributes; + +namespace SortListByProperty; + +[MemoryDiagnoser] +public class SortBenchmarks +{ + private readonly Sort _sort = new(); + private List _originalList = []; + private List _books = []; + + [GlobalSetup] + public void GlobalSetup() + { + _originalList = GenerateBooks(); + } + + // Every invocation sorts a fresh, unsorted copy of the same generated list. + // Without this, the in-place benchmarks would sort an already sorted list + // on every invocation after the first one. + [IterationSetup] + public void IterationSetup() + { + _books = new List(_originalList); + } + + [Benchmark] + public List SortByTitleUsingLinq() + { + return _sort.SortByTitleUsingLinq(_books); + } + + [Benchmark] + public List SortByPagesUsingLinq() + { + return _books.OrderBy(x => x.Pages).ToList(); + } + + [Benchmark] + public List SortByPagesDescendingUsingLinq() + { + return _sort.SortByPagesDescendingUsingLinq(_books); + } + + [Benchmark] + public void SortByPagesIComparable() + { + _books.Sort(); + } + + [Benchmark] + public void SortByTitleIComparer() + { + _books.Sort(new SortBookByTitle()); + } + + [Benchmark] + public void SortByTitleComparisonDelegate() + { + var comparer = new Comparison(Sort.CompareBooks); + + _books.Sort(comparer); + } + + public static List GenerateBooks() + { + var books = new List(); + + for (int i = 0; i < 1000; i++) + { + var book = new Book + { + Title = DataGenerator.GenerateString(10), + Author = DataGenerator.GenerateString(15), + Pages = DataGenerator.GenerateNumber(100, 1000) + }; + + books.Add(book); + } + + return books; + } +} diff --git a/collections-lists/SortListByProperty/SortListByProperty/SortBookByTitle.cs b/collections-lists/SortListByProperty/SortListByProperty/SortBookByTitle.cs index 2786c3c8d6..91ee4e0b88 100644 --- a/collections-lists/SortListByProperty/SortListByProperty/SortBookByTitle.cs +++ b/collections-lists/SortListByProperty/SortListByProperty/SortBookByTitle.cs @@ -1,16 +1,15 @@ -namespace SortListByProperty +namespace SortListByProperty; + +public class SortBookByTitle : IComparer { - public class SortBookByTitle : IComparer + public int Compare(Book? x, Book? y) { - public int Compare(Book x, Book y) - { - if (x == null) - return -1; + if (x == null) + return -1; - if (y == null) - return 1; + if (y == null) + return 1; - return x.Title.CompareTo(y.Title); - } + return x.Title.CompareTo(y.Title); } } diff --git a/collections-lists/SortListByProperty/SortListByProperty/SortListByProperty.csproj b/collections-lists/SortListByProperty/SortListByProperty/SortListByProperty.csproj index 79e7148fd0..62be4f867f 100644 --- a/collections-lists/SortListByProperty/SortListByProperty/SortListByProperty.csproj +++ b/collections-lists/SortListByProperty/SortListByProperty/SortListByProperty.csproj @@ -2,13 +2,13 @@ Exe - net6.0 + net10.0 enable enable - + diff --git a/collections-lists/SortListByProperty/SortListByPropertyTests/SortListByPropertyTests.csproj b/collections-lists/SortListByProperty/SortListByPropertyTests/SortListByPropertyTests.csproj index 7141e17723..ddabe46b4d 100644 --- a/collections-lists/SortListByProperty/SortListByPropertyTests/SortListByPropertyTests.csproj +++ b/collections-lists/SortListByProperty/SortListByPropertyTests/SortListByPropertyTests.csproj @@ -1,17 +1,16 @@ - net6.0 + net10.0 enable false - - - - + + + diff --git a/collections-lists/SortListByProperty/SortListByPropertyTests/Test.cs b/collections-lists/SortListByProperty/SortListByPropertyTests/Test.cs index 186bf0e57a..c348af46f6 100644 --- a/collections-lists/SortListByProperty/SortListByPropertyTests/Test.cs +++ b/collections-lists/SortListByProperty/SortListByPropertyTests/Test.cs @@ -1,147 +1,188 @@ -using Microsoft.VisualStudio.TestTools.UnitTesting; +using Microsoft.VisualStudio.TestTools.UnitTesting; using System; using System.Collections.Generic; +using System.Linq; -namespace SortListByProperty.Tests +namespace SortListByProperty.Tests; + +[TestClass] +public class Test { - [TestClass] - public class Test + private static List _books = []; + private static List _booksSortedTitle = []; + private static List _booksSortedAuthorPages = []; + private static List _booksSortedPages = []; + private static List _booksSortedPagesDescending = []; + + private static readonly Book gatsby = new() + { + Title = "The Great Gatsby", + Author = "F. Scott Fitzgerald", + Pages = 279 + }; + + private static readonly Book lotr = new() + { + Title = "The Lord Of The Rings", + Author = "J.R.R. Tolkien", + Pages = 1216 + }; + + private static readonly Book pride = new() + { + Title = "Pride & Prejudice", + Author = "Jane Austen", + Pages = 329 + }; + + private static readonly Book emma = new() + { + Title = "Emma", + Author = "Jane Austen", + Pages = 1036 + }; + + public Test() { - private static List _books; - private static List _booksSortedTitle; - private static List _booksSortedAuthorPages; - private static List _booksSortedPages; + CreateBookData(); + CreateBookDataSortedByTitle(); + CreateBookDataSortedByAuthorPages(); + CreateBookDataSortedByPages(); + CreateBookDataSortedByPagesDescending(); + } - private static readonly Book gatsby = new Book + private static void CreateBookData() + { + _books = new List { - Title = "The Great Gatsby", - Author = "F. Scott Fitzgerald", - Pages = 279 + lotr, + emma, + gatsby, + pride }; + } - private static readonly Book lotr = new Book + private static void CreateBookDataSortedByTitle() + { + _booksSortedTitle = new List { - Title = "The Lord Of The Rings", - Author = "J.R.R. Tolkien", - Pages = 1216 + emma, + pride, + gatsby, + lotr }; + } - private static readonly Book pride = new Book + private static void CreateBookDataSortedByAuthorPages() + { + _booksSortedAuthorPages = new List { - Title = "Pride & Prejudice", - Author = "Jane Austen", - Pages = 329 + gatsby, + lotr, + pride, + emma }; + } - private static readonly Book emma = new Book + private static void CreateBookDataSortedByPages() + { + _booksSortedPages = new List { - Title = "Emma", - Author = "Jane Austen", - Pages = 1036 + gatsby, + pride, + emma, + lotr }; + } - public Test() + private static void CreateBookDataSortedByPagesDescending() + { + _booksSortedPagesDescending = new List { - CreateBookData(); - CreateBookDataSortedByTitle(); - CreateBookDataSortedByAuthorPages(); - CreateBookDataSortedByPages(); - } + lotr, + emma, + pride, + gatsby + }; + } - private static void CreateBookData() - { - _books = new List - { - gatsby, - lotr, - pride, - emma - }; - } - - private static void CreateBookDataSortedByTitle() - { - _booksSortedTitle = new List - { - emma, - pride, - gatsby, - lotr - }; - } - - private static void CreateBookDataSortedByAuthorPages() - { - _booksSortedAuthorPages = new List - { - gatsby, - lotr, - pride, - emma - }; - } - - private static void CreateBookDataSortedByPages() - { - _booksSortedPages = new List - { - gatsby, - pride, - emma, - lotr - }; - } - - [TestMethod] - public void WhenOrderByTitle_ThenNewListIsSortedByTiTle() - { - var sort = new Sort(); - var sortedList = sort.SortByTitleUsingLinq(_books); + [TestMethod] + public void WhenOrderByTitle_ThenNewListIsSortedByTiTle() + { + var sort = new Sort(); + var sortedList = sort.SortByTitleUsingLinq(_books); - CollectionAssert.AreEqual(_booksSortedTitle, sortedList); - } + CollectionAssert.AreEqual(_booksSortedTitle, sortedList); + } - [TestMethod] - public void WhenOrderByAuthorThenByPages_ThenNewListIsSortedByAuthorAndPages() - { - var sort = new Sort(); - var sortedList = sort.SortByAuthorAndPagesUsingLinq(_books); + [TestMethod] + public void WhenOrderByAuthorThenByPages_ThenNewListIsSortedByAuthorAndPages() + { + var sort = new Sort(); + var sortedList = sort.SortByAuthorAndPagesUsingLinq(_books); - CollectionAssert.AreEqual(_booksSortedAuthorPages, sortedList); - } + CollectionAssert.AreEqual(_booksSortedAuthorPages, sortedList); + } - [TestMethod] - public void WhenUsingIComparableByPages_ThenSameListIsSortedByPages() - { - _books.Sort(); + [TestMethod] + public void WhenOrderByAuthorThenByPages_ThenResultDiffersFromInputAndFromAuthorOnly() + { + var sort = new Sort(); + var sortedList = sort.SortByAuthorAndPagesUsingLinq(_books); + var sortedByAuthorOnly = _books.OrderBy(x => x.Author).ToList(); - CollectionAssert.AreEqual(_booksSortedPages, _books); - } + CollectionAssert.AreNotEqual(_books, sortedList); + CollectionAssert.AreNotEqual(sortedByAuthorOnly, sortedList); + } - [TestMethod] - public void WhenUsingIComparerByTitle_ThenSameListIsSortedByTitle() - { - _books.Sort(new SortBookByTitle()); + [TestMethod] + public void WhenOrderByDescendingPages_ThenNewListIsSortedByPagesDescending() + { + var sort = new Sort(); + var sortedList = sort.SortByPagesDescendingUsingLinq(_books); - CollectionAssert.AreEqual(_booksSortedTitle, _books); - } + CollectionAssert.AreEqual(_booksSortedPagesDescending, sortedList); + } - [TestMethod] - public void WhenUsingComparisonDelegateByTitle_ThenSameListIsSortedByTitle() - { - var bookComparer = new Comparison(Sort.CompareBooks); + [TestMethod] + public void WhenUsingIComparableByPages_ThenSameListIsSortedByPages() + { + _books.Sort(); - _books.Sort(bookComparer); + CollectionAssert.AreEqual(_booksSortedPages, _books); + } - CollectionAssert.AreEqual(_booksSortedTitle, _books); - } + [TestMethod] + public void WhenUsingIComparerByTitle_ThenSameListIsSortedByTitle() + { + _books.Sort(new SortBookByTitle()); - [TestMethod] - public void WhenUsingComparisonDelegateLambdaByTitle_ThenSameListIsSortedByTitle() - { - _books.Sort((x, y) => x.Title.CompareTo(y.Title)); + CollectionAssert.AreEqual(_booksSortedTitle, _books); + } + + [TestMethod] + public void WhenUsingComparisonDelegateByTitle_ThenSameListIsSortedByTitle() + { + var bookComparer = new Comparison(Sort.CompareBooks); + + _books.Sort(bookComparer); + + CollectionAssert.AreEqual(_booksSortedTitle, _books); + } + + [TestMethod] + public void WhenUsingComparisonDelegateLambdaByTitle_ThenSameListIsSortedByTitle() + { + _books.Sort((x, y) => x.Title.CompareTo(y.Title)); + + CollectionAssert.AreEqual(_booksSortedTitle, _books); + } + + [TestMethod] + public void WhenUsingComparisonDelegateLambdaByPagesDescending_ThenSameListIsSortedByPagesDescending() + { + _books.Sort((x, y) => y.Pages.CompareTo(x.Pages)); - CollectionAssert.AreEqual(_booksSortedTitle, _books); - } + CollectionAssert.AreEqual(_booksSortedPagesDescending, _books); } -} \ No newline at end of file +}