Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 16 additions & 17 deletions collections-lists/SortListByProperty/SortListByProperty/Book.cs
Original file line number Diff line number Diff line change
@@ -1,22 +1,21 @@
namespace SortListByProperty
namespace SortListByProperty;

public class Book : IComparable<Book>
{
public class Book : IComparable<Book>
{
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;
}
}
Original file line number Diff line number Diff line change
@@ -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();
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using BenchmarkDotNet.Running;
using BenchmarkDotNet.Running;
using SortListByProperty;

var benchmark = BenchmarkRunner.Run<Sort>();
BenchmarkRunner.Run<SortBenchmarks>();
77 changes: 16 additions & 61 deletions collections-lists/SortListByProperty/SortListByProperty/Sort.cs
Original file line number Diff line number Diff line change
@@ -1,69 +1,24 @@
using BenchmarkDotNet.Attributes;
namespace SortListByProperty;

namespace SortListByProperty
public class Sort
{
public class Sort
public List<Book> SortByTitleUsingLinq(List<Book> originalList)
{
[ArgumentsSource(nameof(GenerateBooks))]
[Benchmark]
public List<Book> SortByTitleUsingLinq(List<Book> originalList)
{
return originalList.OrderBy(x => x.Title).ToList();
}

public List<Book> SortByAuthorAndPagesUsingLinq(List<Book> originalList)
{
return originalList.OrderBy(x => x.Author).ThenBy(x => x.Pages).ToList();
}

[ArgumentsSource(nameof(GenerateBooks))]
[Benchmark]
public void SortByTitleIComparable(List<Book> originalList)
{
originalList.Sort();
}

[ArgumentsSource(nameof(GenerateBooks))]
[Benchmark]
public void SortByTitleIComparer(List<Book> originalList)
{
originalList.Sort(new SortBookByTitle());
}

[ArgumentsSource(nameof(GenerateBooks))]
[Benchmark]
public void SortByTitleComparisonDelegate(List<Book> originalList)
{
var comparer = new Comparison<Book>(Sort.CompareBooks);

originalList.Sort(comparer);
}

public static int CompareBooks(Book x, Book y)
{
return x.Title.CompareTo(y.Title);
}

public IEnumerable<List<Book>> GenerateBooks()
{
var data = new List<List<Book>>();
var books = new List<Book>();

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<Book> SortByAuthorAndPagesUsingLinq(List<Book> originalList)
{
return originalList.OrderBy(x => x.Author).ThenBy(x => x.Pages).ToList();
}

data.Add(books);
public List<Book> SortByPagesDescendingUsingLinq(List<Book> originalList)
{
return originalList.OrderByDescending(x => x.Pages).ToList();
}

return data;
}
public static int CompareBooks(Book x, Book y)
{
return x.Title.CompareTo(y.Title);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
using BenchmarkDotNet.Attributes;

namespace SortListByProperty;

[MemoryDiagnoser]
public class SortBenchmarks
{
private readonly Sort _sort = new();
private List<Book> _originalList = [];
private List<Book> _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<Book>(_originalList);
}

[Benchmark]
public List<Book> SortByTitleUsingLinq()
{
return _sort.SortByTitleUsingLinq(_books);
}

[Benchmark]
public List<Book> SortByPagesUsingLinq()
{
return _books.OrderBy(x => x.Pages).ToList();
}

[Benchmark]
public List<Book> 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<Book>(Sort.CompareBooks);

_books.Sort(comparer);
}

public static List<Book> GenerateBooks()
{
var books = new List<Book>();

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;
}
}
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
namespace SortListByProperty
namespace SortListByProperty;

public class SortBookByTitle : IComparer<Book>
{
public class SortBookByTitle : IComparer<Book>
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);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="BenchmarkDotNet" Version="0.13.1" />
<PackageReference Include="BenchmarkDotNet" Version="0.15.8" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<TargetFramework>net10.0</TargetFramework>
<Nullable>enable</Nullable>

<IsPackable>false</IsPackable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.11.0" />
<PackageReference Include="MSTest.TestAdapter" Version="2.2.7" />
<PackageReference Include="MSTest.TestFramework" Version="2.2.7" />
<PackageReference Include="coverlet.collector" Version="3.1.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.10.1" />
<PackageReference Include="MSTest" Version="4.4.1" />
<PackageReference Include="coverlet.collector" Version="10.1.0" />
</ItemGroup>

<ItemGroup>
Expand Down
Loading
Loading