Adding LanguagePrimitives.TryCompare to provide faster comparisons#7438
Adding LanguagePrimitives.TryCompare to provide faster comparisons#7438daxian-dbw merged 7 commits intoPowerShell:masterfrom
Conversation
d767118 to
296db72
Compare
|
The remaining CodeFactor issues are intentionally left that way to match the style of similar code in the same file. |
ae34a95 to
0553541
Compare
This can be used by OrderObjectBase to have a faster code path that doesn't throw exceptions.
0553541 to
1416a78
Compare
Seem typo in the PR description. |
There was a problem hiding this comment.
Please add name for const argument ignoreCase: false.
There was a problem hiding this comment.
We use -BeExactly for string only. Here we expect an integer and should use -Be.
Please review using -BeExactly below too.
| formatProvider = CultureInfo.InvariantCulture; | ||
| } | ||
|
|
||
| if (!(formatProvider is CultureInfo culture)) |
There was a problem hiding this comment.
Why we use IFormatProvider parameter type if we want get CultureInfo?
There was a problem hiding this comment.
I'm not inventing a new API here, just providing a Try alternative to the existing one.
If that API should be changed seems like a separate discussion.
There was a problem hiding this comment.
I think we should use "dry" principle and use the function everywhere in the file.
| { | ||
| if (!(second is string secondString)) | ||
| { | ||
| if (!TryConvertTo(second, culture, out secondString)) |
There was a problem hiding this comment.
We could replace the two if-s with one.
|
@PowerShell/powershell-committee reviewed this and is fine with the api additions. Thanks. |
| { | ||
| // Note that this will occur if the objects do not support | ||
| // IComparable. We fall back to comparing as strings. | ||
| return result * (_ascendingOrder ? 1 : -1); |
There was a problem hiding this comment.
Do we get some win if we exclude multiplication?
There was a problem hiding this comment.
I'd leave that to the compiler and the JIT. They usually do a good job on things like this.
|
|
||
|
|
||
|
|
||
| if (first == null && second == null) |
There was a problem hiding this comment.
Please remove extra empty lines above.
| default: return -1; | ||
| } | ||
| } | ||
| return second == null ? 0 : CompareObjectToNull(second, true); |
There was a problem hiding this comment.
Nit: CompareObjectToNull(second, numberIsRightHandSide:true)
| case TypeCode.Decimal: return System.Math.Sign((System.Decimal)first) < 0 ? -1 : 1; | ||
| default: return 1; | ||
| } | ||
| return CompareObjectToNull(first, false); |
There was a problem hiding this comment.
Nit: CompareObjectToNull(first, numberIsRightHandSide:false)
|
|
||
| if (first == null) | ||
| { | ||
| result = CompareObjectToNull(second, true); |
There was a problem hiding this comment.
Nit: CompareObjectToNull(second, numberIsRighthandSide:true)
| { | ||
| // If it's a positive number, including 0, it's greater than null | ||
| // for everything else it's less than zero... | ||
| result = CompareObjectToNull(first, false); |
| { | ||
| if (!(second is string secondString)) | ||
| { | ||
| if (!TryConvertTo(second, culture, out secondString)) |
There was a problem hiding this comment.
TryConvertTo() uses ConversionData.Invoke() which throws exceptions for invalid casts. Have you considered adding a "TryInvoke" method to avoid the exception, for performance?
There was a problem hiding this comment.
@PaulHigin I recently changed TryConvertTo to check the result of FigureConvertion and exit early, without invoking ConversionData.Invoke() if the ConvertionRank is None.
So, yes, I have avoided the exception in many but not all cases. Interesting take to put it on ConversionData. That is arguably where it belongs.
|
Whoops, I just saw that this has already been merged. None of my comments are blocking. |
PR Summary
This PR adds the
TryCompareequivalent ofCompare, just as we have aTryConvertalternative toConvert.This enables faster comparison in the cases where the convertions throws exception.
As an example:
takes
3 800 msbefore and280 msafter.takes
20 sbefore and15 safter.It is implemented equivalently to
LanguagePrimitives.Compare, but returning false whereComparewould have thrown an exception.This is adding a new public API to
LanguagePrimitives, so it will probably need a committee approval.The new APIs are:
The new APIs are used by
ObjectCommandPropertyValue(used by sort-object and group-object) andFormatGroupManager.PR Checklist
.h,.cpp,.cs,.ps1and.psm1files have the correct copyright headerWIP:to the beginning of the title and remove the prefix when the PR is ready.[feature]if the change is significant or affects feature tests