Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Commit cb1e8b9

Browse files
committed
Remove some boxing from tuples with >= 8 elements
Take advantage of #14698 to avoid boxing the TRest argument and improve devirtualization.
1 parent 1894302 commit cb1e8b9

File tree

1 file changed

+24
-20
lines changed

1 file changed

+24
-20
lines changed

src/System.Private.CoreLib/shared/System/ValueTuple.cs

Lines changed: 24 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2018,8 +2018,8 @@ int IStructuralComparable.CompareTo(object? other, IComparer comparer)
20182018
/// <returns>A 32-bit signed integer hash code.</returns>
20192019
public override int GetHashCode()
20202020
{
2021-
// We want to have a limited hash in this case. We'll use the last 8 elements of the tuple
2022-
if (!(Rest is IValueTupleInternal rest))
2021+
// We want to have a limited hash in this case. We'll use the first 7 elements of the tuple
2022+
if (!(Rest is IValueTupleInternal))
20232023
{
20242024
return HashCode.Combine(Item1?.GetHashCode() ?? 0,
20252025
Item2?.GetHashCode() ?? 0,
@@ -2030,46 +2030,50 @@ public override int GetHashCode()
20302030
Item7?.GetHashCode() ?? 0);
20312031
}
20322032

2033-
int size = rest.Length;
2034-
if (size >= 8) { return rest.GetHashCode(); }
2033+
int size = ((IValueTupleInternal)Rest).Length;
2034+
int restHashCode = Rest.GetHashCode();
2035+
if (size >= 8)
2036+
{
2037+
return restHashCode;
2038+
}
20352039

2036-
// In this case, the rest member has less than 8 elements so we need to combine some our elements with the elements in rest
2040+
// In this case, the rest member has less than 8 elements so we need to combine some of our elements with the elements in rest
20372041
int k = 8 - size;
20382042
switch (k)
20392043
{
20402044
case 1:
20412045
return HashCode.Combine(Item7?.GetHashCode() ?? 0,
2042-
rest.GetHashCode());
2046+
restHashCode);
20432047
case 2:
20442048
return HashCode.Combine(Item6?.GetHashCode() ?? 0,
20452049
Item7?.GetHashCode() ?? 0,
2046-
rest.GetHashCode());
2050+
restHashCode);
20472051
case 3:
20482052
return HashCode.Combine(Item5?.GetHashCode() ?? 0,
20492053
Item6?.GetHashCode() ?? 0,
20502054
Item7?.GetHashCode() ?? 0,
2051-
rest.GetHashCode());
2055+
restHashCode);
20522056
case 4:
20532057
return HashCode.Combine(Item4?.GetHashCode() ?? 0,
20542058
Item5?.GetHashCode() ?? 0,
20552059
Item6?.GetHashCode() ?? 0,
20562060
Item7?.GetHashCode() ?? 0,
2057-
rest.GetHashCode());
2061+
restHashCode);
20582062
case 5:
20592063
return HashCode.Combine(Item3?.GetHashCode() ?? 0,
20602064
Item4?.GetHashCode() ?? 0,
20612065
Item5?.GetHashCode() ?? 0,
20622066
Item6?.GetHashCode() ?? 0,
20632067
Item7?.GetHashCode() ?? 0,
2064-
rest.GetHashCode());
2068+
restHashCode);
20652069
case 6:
20662070
return HashCode.Combine(Item2?.GetHashCode() ?? 0,
20672071
Item3?.GetHashCode() ?? 0,
20682072
Item4?.GetHashCode() ?? 0,
20692073
Item5?.GetHashCode() ?? 0,
20702074
Item6?.GetHashCode() ?? 0,
20712075
Item7?.GetHashCode() ?? 0,
2072-
rest.GetHashCode());
2076+
restHashCode);
20732077
case 7:
20742078
case 8:
20752079
return HashCode.Combine(Item1?.GetHashCode() ?? 0,
@@ -2079,7 +2083,7 @@ public override int GetHashCode()
20792083
Item5?.GetHashCode() ?? 0,
20802084
Item6?.GetHashCode() ?? 0,
20812085
Item7?.GetHashCode() ?? 0,
2082-
rest.GetHashCode());
2086+
restHashCode);
20832087
}
20842088

20852089
Debug.Fail("Missed all cases for computing ValueTuple hash code");
@@ -2093,7 +2097,7 @@ int IStructuralEquatable.GetHashCode(IEqualityComparer comparer)
20932097

20942098
private int GetHashCodeCore(IEqualityComparer comparer)
20952099
{
2096-
// We want to have a limited hash in this case. We'll use the last 8 elements of the tuple
2100+
// We want to have a limited hash in this case. We'll use the first 7 elements of the tuple
20972101
if (!(Rest is IValueTupleInternal rest))
20982102
{
20992103
return HashCode.Combine(comparer.GetHashCode(Item1!), comparer.GetHashCode(Item2!), comparer.GetHashCode(Item3!),
@@ -2151,19 +2155,19 @@ int IValueTupleInternal.GetHashCode(IEqualityComparer comparer)
21512155
/// </remarks>
21522156
public override string ToString()
21532157
{
2154-
if (Rest is IValueTupleInternal rest)
2158+
if (Rest is IValueTupleInternal)
21552159
{
2156-
return "(" + Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ", " + Item5?.ToString() + ", " + Item6?.ToString() + ", " + Item7?.ToString() + ", " + rest.ToStringEnd();
2160+
return "(" + Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ", " + Item5?.ToString() + ", " + Item6?.ToString() + ", " + Item7?.ToString() + ", " + ((IValueTupleInternal)Rest).ToStringEnd();
21572161
}
21582162

21592163
return "(" + Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ", " + Item5?.ToString() + ", " + Item6?.ToString() + ", " + Item7?.ToString() + ", " + Rest.ToString() + ")";
21602164
}
21612165

21622166
string IValueTupleInternal.ToStringEnd()
21632167
{
2164-
if (Rest is IValueTupleInternal rest)
2168+
if (Rest is IValueTupleInternal)
21652169
{
2166-
return Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ", " + Item5?.ToString() + ", " + Item6?.ToString() + ", " + Item7?.ToString() + ", " + rest.ToStringEnd();
2170+
return Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ", " + Item5?.ToString() + ", " + Item6?.ToString() + ", " + Item7?.ToString() + ", " + ((IValueTupleInternal)Rest).ToStringEnd();
21672171
}
21682172

21692173
return Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ", " + Item5?.ToString() + ", " + Item6?.ToString() + ", " + Item7?.ToString() + ", " + Rest.ToString() + ")";
@@ -2172,7 +2176,7 @@ string IValueTupleInternal.ToStringEnd()
21722176
/// <summary>
21732177
/// The number of positions in this data structure.
21742178
/// </summary>
2175-
int ITuple.Length => Rest is IValueTupleInternal rest ? 7 + rest.Length : 8;
2179+
int ITuple.Length => Rest is IValueTupleInternal ? 7 + ((IValueTupleInternal)Rest).Length : 8;
21762180

21772181
/// <summary>
21782182
/// Get the element at position <param name="index"/>.
@@ -2199,9 +2203,9 @@ string IValueTupleInternal.ToStringEnd()
21992203
return Item7;
22002204
}
22012205

2202-
if (Rest is IValueTupleInternal rest)
2206+
if (Rest is IValueTupleInternal)
22032207
{
2204-
return rest[index - 7];
2208+
return ((IValueTupleInternal)Rest)[index - 7];
22052209
}
22062210

22072211

0 commit comments

Comments
 (0)