Skip to content
This repository has been archived by the owner on Jan 23, 2023. It is now read-only.
/ corefx Public archive

Add Span SequenceCompareTo extension method #26232

Merged
merged 8 commits into from
Jan 10, 2018

Conversation

ahsonkhan
Copy link
Member

Fixes https://github.com/dotnet/corefx/issues/16878

  • Added unit and perf tests
  • Vectorized the SequenceCompareTo<byte> implementation
  • Note: I did not loop unroll SequenceCompareTo<T> similar to SequenceEqual<T> since I observed no performance improvement (in fact there was some regression for T = int)

cc @KrzysztofCwalina, @jkotas, @atsushikan, @AronParker, @Bobris

Debug.Assert(secondLength >= 0);

if (Unsafe.AreSame(ref first, ref second))
goto Equal;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

return firstLength.CompareTo(secondLength); can be right here. I do not think you are getting anything by jumping to it.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would say this "AreSame" will be optimization only in very rare cases, but if you see it as useful, then goto solution will generate shorter native code, so I am for leaving it there.

int result = Unsafe.AddByteOffset(ref first, i).CompareTo(Unsafe.AddByteOffset(ref second, i));
if (result != 0) return result;
i += 1;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Direct return 0; would be better, I think.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where would I return 0? After the loop ends, we may still return other values.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After the loop ends, you know that the two sequences are 100% equal. No?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I have misread this ... I though that the first statement is comparing the lengths.

Copy link
Member

@jkotas jkotas Jan 9, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your implementation was fine as it was. (Also ignore the other comment.)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, minLength is the length of the smaller sequence. The lengths could be different still.

}

Equal:
return firstLength.CompareTo(secondLength);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am for changing this to simple return firstLength-secondLength (because lengths could be only positive there cannot happen any bad overflow).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wanted the results here to be consistent with the existing int.CompareTo. Subtracting could result in values other than {-1, 1, 0}. I am not sure if the performance win is worth the inconsistency. Thoughts?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The contract for Compare methods is to return positive, 0, negative. It is not necessary to normalize to -1,1,0 - other paths in your implementation do not normalize either.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The contract for Compare methods is to return positive, 0, negative. It is not necessary to normalize to -1,1,0

Fair point

other paths in your implementation do not normalize either.

Where? Every comparison uses the CompareTo method (at least for T = byte), as far as I can tell.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Byte.CompareTo method also does not return just -1, 1, 0 (it is also simple subtraction). Only int one have to due to possibility of overflow for negative inputs. And because of mispredicted comparisons in int.CompareTo overhead could be nontrivial, but it is harder to measure...

@ahsonkhan
Copy link
Member Author

Is this PR good to go?

@ahsonkhan ahsonkhan merged commit 7931769 into dotnet:master Jan 10, 2018
@ahsonkhan ahsonkhan deleted the SequenceCompare branch January 10, 2018 23:44
@karelz karelz added this to the 2.1.0 milestone Jan 20, 2018
@ahsonkhan ahsonkhan mentioned this pull request Jan 25, 2018
picenka21 pushed a commit to picenka21/runtime that referenced this pull request Feb 18, 2022
* Add SequenceCompareTo initial

* Update tests and remove use of Dangerous API

* Add SequenceCompareTo performance test and loop unroll

* Revert loop unrolling SequenceCompareTo

* Vectorize SequenceCompareTo<byte>

* Fix performance test class name.

* Address PR feedback


Commit migrated from dotnet/corefx@7931769
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants