Optimize ReadOnlySequence.First for the common case#33000
Optimize ReadOnlySequence.First for the common case#33000ahsonkhan merged 5 commits intodotnet:masterfrom
Conversation
| ThrowHelper.ThrowInvalidOperationException_EndPositionNotReached(); | ||
|
|
||
| if (endIndex >= 0) // SequenceType.MultiSegment | ||
| if (typeof(T) == typeof(char) && startObject.GetType() == typeof(string)) |
There was a problem hiding this comment.
The other thing I was wondering was whether or not it would measure to have an extension method of GetFirstBuffer() public and have an explicit overload for byte? Or possibly have one that also returns the next position as well? E.g. anything that could improve the construction of a reader.
|
@ahsonkhan, I'm going to explore another approach today as well. I'm going to explore adding more straight-forward state to the struct. I think it may pan out, especially given that there are free gaps on x64 given alignment requirements. @jkotas- can you correct me if I'm wrong? Given that this is made up of two The cost of accessing |
You can try it. I do not know on top of my head what happens here. |
Unfortunately it appears that you can't take advantage of the empty space. The best starting option (for my investigations) appears to be adding another int to |
|
@ahsonkhan, what's the plan here? Close? Review further? Thanks. |
|
@ahsonkhan ping? |
…into OptimizeSequenceFirst
|
I resolved the merge conflict and the PR can now be merged, unless there is other feedback. |
| if (startIndex >= 0) | ||
| // A == 0 && B == 0 means SequenceType.MultiSegment | ||
| // Equivalent to startIndex >= 0 && endIndex >= 0 | ||
| if ((startIndex >> 31) + (endIndex >> 31) == 0) |
There was a problem hiding this comment.
If you want to play cryptic bit tricks, this can be written as (startIndex | endIndex) >= 0 to save a few more instructions.
|
Sorry to jump in, but I couldn't avoid seeing a commit in this PR that is called |
) * Optimize ReadOnlySequence.First for the common case * Add back bit mask flags * Revert back to type-safe casts * Address PR feedback. Commit migrated from dotnet/corefx@a7b5f8c
Inspired from dotnet/coreclr#20386Does it make sense to go down this path?The bulk of the savings is coming from moving the MemoryManager code path out to a separate method to make the method that is getting inlined smaller.
The remainder is coming from using unsafe casts and using aMemoryManagerHolderclass (which means more allocations for that particular case).Results from this benchmark:
corefx/src/System.Memory/tests/Performance/Perf.ReadOnlySequence.First.cs
Line 12 in e67b429
Out-dated results