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
Optimize BeEquivalentTo
#1939
Optimize BeEquivalentTo
#1939
Changes from all commits
373a6ad
6c5db11
981570b
8da904f
370c674
a741e66
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,6 @@ | ||
using System; | ||
using System.Collections; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Text.RegularExpressions; | ||
using FluentAssertions.Common; | ||
|
@@ -13,15 +14,35 @@ public class Node : INode | |
{ | ||
private static readonly Regex MatchFirstIndex = new(@"^\[\d+\]$"); | ||
|
||
private string path; | ||
private string name; | ||
private string pathAndName; | ||
|
||
public GetSubjectId GetSubjectId { get; protected set; } = () => string.Empty; | ||
|
||
public Type Type { get; protected set; } | ||
|
||
public string Path { get; protected set; } | ||
public string Path | ||
{ | ||
get => path; | ||
protected set | ||
{ | ||
path = value; | ||
pathAndName = null; | ||
} | ||
} | ||
|
||
public string PathAndName => Path.Combine(Name); | ||
public string PathAndName => pathAndName ??= Path.Combine(Name); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this really that expensive? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Expensiveness might be a relative term, as it has to compared against code maintainability. The operation of concatenating strings (of course) depends on the length of the member name and how far down the member path we are. Many of the calls to The remaining calls to
For this example below the caching of var subject = new MyClass[]
{
new () { Value = 1, Inner = new () { Value = 2 } },
new () { Value = 1, Inner = new () { Value = 2 } },
new () { Value = 1, Inner = new () { Value = 2 } },
new () { Value = 1, Inner = new () { Value = 2 } },
new () { Value = 1, Inner = new () { Value = 2 } },
};
var expected = = new MyClass[]
{
new () { Value = 1, Inner = new () { Value = 2 } },
new () { Value = 1, Inner = new () { Value = 2 } },
new () { Value = 1, Inner = new () { Value = 2 } },
new () { Value = 1, Inner = new () { Value = 2 } },
new () { Value = 1, Inner = new () { Value = 2 } },
};
subject.Should().BeEquivalentTo(expected); |
||
|
||
public string Name { get; set; } | ||
public string Name | ||
{ | ||
get => name; | ||
set | ||
{ | ||
name = value; | ||
pathAndName = null; | ||
} | ||
} | ||
|
||
public virtual string Description => $"{GetSubjectId().Combine(PathAndName)}"; | ||
|
||
|
@@ -109,14 +130,17 @@ public override bool Equals(object obj) | |
return Equals((Node)obj); | ||
} | ||
|
||
private bool Equals(Node other) => Type == other.Type && PathAndName == other.PathAndName; | ||
private bool Equals(Node other) => (Type, Name, Path) == (other.Type, other.Name, other.Path); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The change from two to three branches is the cause of the remaining decrease in branch coverage. |
||
|
||
public override int GetHashCode() | ||
{ | ||
unchecked | ||
{ | ||
#pragma warning disable CA1307 | ||
return (Type.GetHashCode() * 397) ^ PathAndName.GetHashCode(); | ||
int hashCode = Type.GetHashCode(); | ||
hashCode = (hashCode * 397) + Path.GetHashCode(); | ||
hashCode = (hashCode * 397) + Name.GetHashCode(); | ||
return hashCode; | ||
} | ||
} | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In develop the lambda is constructed in each iteration no matter if we enter the
if
or not.See the difference on
sharplab