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

Conversation

@benaadams
Copy link
Member

@benaadams benaadams commented Nov 19, 2018

x 2.5 times faster at position 0
x 11.2 times faster at position 1024

For

// where comparisonType == StringComparison.Ordinal 
string.IndexOf(string value, StringComparison comparisonType)
string.IndexOf(string value, int startIndex, StringComparison comparisonType)
string.IndexOf(string value, int startIndex, int count, StringComparison comparisonType)

// where T : char
IndexOf<T>(this Span<T> span, ReadOnlySpan<T> value)
IndexOf<T>(this ReadOnlySpan<T> span, ReadOnlySpan<T> value)

// where comparisonType == StringComparison.Ordinal
IndexOf(this ReadOnlySpan<char> span, ReadOnlySpan<char> value, StringComparison comparisonType)

// where options = CompareOptions.Ordinal 
CompareInfo.IndexOf(string source, string value, CompareOptions options)
CompareInfo.IndexOf(string source, string value, int startIndex, CompareOptions options)
CompareInfo.IndexOf(string source, string value, int startIndex, int count, CompareOptions options)

https://gist.github.com/benaadams/177d989fea110f51fab14cd708239852

           Method | Position |      Mean |
 ---------------- |--------- |----------:|
- IndexOf_Ordinal |        0 |  35.86 ns |
+ IndexOf_Ordinal |        0 |  14.15 ns |
- IndexOf_Ordinal |        7 |  42.69 ns |
+ IndexOf_Ordinal |        7 |  19.00 ns |
- IndexOf_Ordinal |        8 |  43.13 ns |
+ IndexOf_Ordinal |        8 |  18.90 ns |
- IndexOf_Ordinal |       15 |  49.67 ns |
+ IndexOf_Ordinal |       15 |  19.61 ns |
- IndexOf_Ordinal |       16 |  47.58 ns |
+ IndexOf_Ordinal |       16 |  19.64 ns |
- IndexOf_Ordinal |       31 |  60.92 ns |
+ IndexOf_Ordinal |       31 |  21.09 ns |
- IndexOf_Ordinal |       32 |  62.66 ns |
+ IndexOf_Ordinal |       32 |  21.11 ns |
- IndexOf_Ordinal |       63 | 100.10 ns |
+ IndexOf_Ordinal |       63 |  22.45 ns |
- IndexOf_Ordinal |       64 | 100.82 ns |
+ IndexOf_Ordinal |       64 |  22.54 ns |
- IndexOf_Ordinal |      127 | 156.94 ns |
+ IndexOf_Ordinal |      127 |  27.10 ns |
- IndexOf_Ordinal |      128 | 155.85 ns |
+ IndexOf_Ordinal |      128 |  26.07 ns |
- IndexOf_Ordinal |      255 | 265.79 ns |
+ IndexOf_Ordinal |      255 |  32.93 ns |
- IndexOf_Ordinal |      256 | 266.91 ns |
+ IndexOf_Ordinal |      256 |  32.98 ns |
- IndexOf_Ordinal |     1023 | 918.89 ns |
+ IndexOf_Ordinal |     1023 |  81.13 ns |
- IndexOf_Ordinal |     1024 | 916.90 ns |
+ IndexOf_Ordinal |     1024 |  81.20 ns |

Contributes to https://github.com/dotnet/coreclr/issues/19672

/cc @jkotas, @krwq@tarekgh

// TODO: Instead of this method could we just have upstack code call IndexOfOrdinal with ignoreCase = false?
private static unsafe int FastIndexOfString(string source, string target, int startIndex, int sourceCount, int targetCount, bool findLastIndex)
// TODO: Instead of this method could we just have upstack code call LastIndexOfOrdinal with ignoreCase = false?
private static unsafe int FastLastIndexOfString(string source, string target, int startIndex, int sourceCount, int targetCount)
Copy link
Member Author

Choose a reason for hiding this comment

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

Just removed the forward index, last index is still handled here. Ignoring whitespace shows removal more clearly https://github.com/dotnet/coreclr/pull/21076/files?w=1

@benaadams
Copy link
Member Author

OSX10.12 infra issue: xunit/xunit#1855

@benaadams
Copy link
Member Author

@dotnet-bot test OSX10.12 x64 Checked Innerloop Build and Test please

@benaadams
Copy link
Member Author

@dotnet-bot test OSX10.12 x64 Checked Innerloop Build and Test please

@benaadams
Copy link
Member Author

OSX Fail

.GetFileSizeEx: ERROR -> SetEndOfFile failed due to lack of disk space

@benaadams
Copy link
Member Author

@dotnet-bot test OSX10.12 x64 Checked Innerloop Build and Test please

@benaadams
Copy link
Member Author

OSX Fail

.GetFileSizeEx: ERROR -> SetEndOfFile failed due to lack of disk space

@benaadams
Copy link
Member Author

@dotnet-bot test OSX10.12 x64 Checked Innerloop Build and Test please

@benaadams
Copy link
Member Author

I think OSX CI is generally broken

@tarekgh
Copy link
Member

tarekgh commented Nov 19, 2018

CC @dotnet/dnceng for OSX leg failures

@krwq
Copy link
Member

krwq commented Nov 19, 2018

I assume there already are test cases checking for all of the edge cases we could hit here?

@MattGal
Copy link
Member

MattGal commented Nov 19, 2018

@benaadams @tarekgh : note that running out of disk space on an OSX machine does not make OSX CI generally broken since after finishing their current Jenkins agent job these machines will in most cases (except when jusssssst enough cleanup happens after the agent finishes) will not take more work. In the retry case, the machine its running on currently still has 18 GB free space and will hopefully succeed.

Jenkins in general rarely cleans up workspaces, so it's a constant battle to clean up these machines.


// Found the first element of "value". See if the tail matches.
if (SequenceEqual(
ref Unsafe.As<char, byte>(ref Unsafe.Add(ref searchSpace, index + 1)),
Copy link
Member

Choose a reason for hiding this comment

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

Is it ever possible for index to be Int32.MaxValue, causing this addition to integer overflow? I think the answer is no (because IndexOf should never return that value) but am having trouble convincing myself of this.

Copy link
Member Author

@benaadams benaadams Nov 20, 2018

Choose a reason for hiding this comment

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

Rearranged to avoid 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.

Also the byte version

@benaadams benaadams force-pushed the Vectorize-string.IndexOf(-,-StringComparison.Ordinal) branch from 2252666 to 66b681d Compare November 20, 2018 04:39
2 callers expect value.Length == 0 to be tested first
3rd caller ReplaceCore doesn't allow a value.Length == 0 so moving it
first is ok
@jkotas jkotas merged commit b526aff into dotnet:master Nov 21, 2018
@jkotas
Copy link
Member

jkotas commented Nov 21, 2018

Thank you!

@benaadams benaadams deleted the Vectorize-string.IndexOf(-,-StringComparison.Ordinal) branch November 21, 2018 01:13
picenka21 pushed a commit to picenka21/runtime that referenced this pull request Feb 18, 2022
…lr#21076)

* Vectorize string.IndexOf(..., StringComparison.Ordinal)

* Merge two IndexOf(..., int* matchLengthPtr)

* fix

2 callers expect value.Length == 0 to be tested first
3rd caller ReplaceCore doesn't allow a value.Length == 0 so moving it
first is ok


Commit migrated from dotnet/coreclr@b526aff
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants