Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

01 - Optimize position table - part 1 #1

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
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
Binary file added 01.diagsession
Binary file not shown.
Binary file added imgs/visual-studio-profiler-01.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions src/DotNetPerf.Domain/Outrights/Calculator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ private static TablePositionHistory Simulate(int simulations, IEnumerable<Team>
match.Reset();
}

table.Sort();

tablePositionHistory.Update(table);

table.Reset();
Expand Down
31 changes: 19 additions & 12 deletions src/DotNetPerf.Domain/Outrights/Position.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,31 @@

namespace DotNetPerf.Domain.Outrights;

public sealed record Position : IComparable<Position>
public record struct Position : IComparable<Position>
{
public Position(Team team)
{
Team = team;
Played = 0;
Won = 0;
Drawn = 0;
Lost = 0;
GoalsFor = 0;
GoalsAgainst = 0;
GoalDifference = 0;
Points = 0;
}

public Team Team { get; }
public readonly Team Team { get; }

public int Played { get; private set; }
public int Won { get; private set; }
public int Drawn { get; private set; }
public int Lost { get; private set; }
public int GoalsFor { get; private set; }
public int GoalsAgainst { get; private set; }
public int GoalDifference { get; private set; }
public int Points { get; private set; }
public int Played { readonly get; private set; }
public int Won { readonly get; private set; }
public int Drawn { readonly get; private set; }
public int Lost { readonly get; private set; }
public int GoalsFor { readonly get; private set; }
public int GoalsAgainst { readonly get; private set; }
public int GoalDifference { readonly get; private set; }
public int Points { readonly get; private set; }

public void AddMatch(Match match)
{
Expand Down Expand Up @@ -64,11 +72,10 @@ public void Reset()
Points = 0;
}

public int CompareTo(Position? other)
public int CompareTo(Position other)
{
return other switch
{
null => -1,
var p when Points == p.Points => (GoalDifference - p.GoalDifference) switch
{
0 => 0,
Expand Down
44 changes: 34 additions & 10 deletions src/DotNetPerf.Domain/Outrights/Table.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,35 +2,59 @@

public sealed record Table
{
private readonly List<Position> _positions;
private readonly Position[] _positions;
private readonly Dictionary<Team, int> _map;

public int Count => _positions.Count;
public int Count => _positions.Length;

public Position this[int index] => _positions[index];
public ref readonly Position this[int index] => ref _positions[index];

public Table(IEnumerable<Team> teams)
{
_positions = new (teams.Count());
_positions = new Position[teams.Count()];
_map = new(teams.Count());
var positionIndex = 0;
foreach (var team in teams)
_positions.Add(new Position(team));
{
_positions[positionIndex] = new Position(team);
_map[team] = positionIndex++;
}
}

public void AddResult(Match match)
{
var homePosition = _positions.Single(p => p?.Team == match.HomeTeam);
var awayPosition = _positions.Single(p => p?.Team == match.AwayTeam);
var positions = _positions;

ref var homePosition = ref positions[_map[match.HomeTeam]];
ref var awayPosition = ref positions[_map[match.AwayTeam]];

homePosition.AddMatch(match);
awayPosition.AddMatch(match);
}

_positions.Sort();
public void Sort()
{
Span<Position> positions = _positions;

positions.Sort();
for (int i = 0; i < positions.Length; i++)
{
ref readonly var position = ref positions[i];
_map[position.Team] = i;
}
}

public List<Position>.Enumerator GetEnumerator() => _positions.GetEnumerator();
public ReadOnlySpan<Position>.Enumerator GetEnumerator()
{
ReadOnlySpan<Position> positions = _positions;
return positions.GetEnumerator();
}

public void Reset()
{
foreach (var position in _positions)
Span<Position> positions = _positions;

foreach (ref var position in positions)
position.Reset();
}
}
2 changes: 1 addition & 1 deletion src/DotNetPerf.Domain/Outrights/TablePositionHistory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public void Update(Table table)
{
for (int i = 0; i < table.Count; i++)
{
var position = table[i];
ref readonly var position = ref table[i];
_map[position.Team][i]++;
}
}
Expand Down
2 changes: 1 addition & 1 deletion tests/DotNetPerf.Benchmarks/Outrights/Outrights.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ namespace DotNetPerf.Benchmarks.Outrights;
[MemoryDiagnoser]
[DisassemblyDiagnoser(maxDepth: 3)]
//[EtwProfiler]
[EventPipeProfiler(EventPipeProfile.CpuSampling)]
//[EventPipeProfiler(EventPipeProfile.CpuSampling)]
public class Outrights
{
private CalculateOutrights _input;
Expand Down
8 changes: 4 additions & 4 deletions tests/DotNetPerf.Benchmarks/Outrights/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,14 @@ AMD Ryzen 5 5600X, 1 CPU, 12 logical and 6 physical cores


```
| Method | Simulations | Mean | Error | StdDev | Gen 0 | Code Size | Allocated |
|---------- |------------ |---------:|--------:|--------:|----------:|----------:|----------:|
| Calculate | 1000 | 299.4 ms | 5.85 ms | 5.75 ms | 5000.0000 | 0 MB | 84 MB |
| Method | Simulations | Mean | Error | StdDev | Code Size | Allocated |
|---------- |------------ |---------:|---------:|---------:|----------:|----------:|
| Calculate | 1000 | 47.85 ms | 0.400 ms | 0.374 ms | 8 KB | 82 KB |


#### Visual Studio 2022 profiler

![Visual Studio 2022 profiler](/imgs/visual-studio-profiler.png)
![Visual Studio 2022 profiler](/imgs/visual-studio-profiler-01.png)

#### Other tools

Expand Down