Created
March 1, 2016 06:32
-
-
Save bbowyersmyth/9c13d6873b9a888f7bb7 to your computer and use it in GitHub Desktop.
ReplaceChar
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using BenchmarkDotNet; | |
using BenchmarkDotNet.Attributes; | |
using System; | |
namespace ConsoleApplication2 | |
{ | |
[Config("jobs=RyuJitX64")] | |
public class Replace | |
{ | |
[Params(5, 12, 26, 100, 1000)] | |
public int length = 0; | |
public string _string; | |
[Setup] | |
public void Setup() | |
{ | |
_string = new string('a', length); | |
char[] _chars = _string.ToCharArray(); | |
// Every 10th char | |
for (int i = 9; i < _chars.Length; i += 10) | |
{ | |
_chars[i] = '/'; | |
} | |
// Last char | |
//_chars[length - 1] = '/'; | |
_string = new string(_chars); | |
} | |
[Benchmark] | |
public string ClrReplaceBench() | |
{ | |
return ClrReplace(_string, '/', 'X'); | |
} | |
[Benchmark] | |
public string RtReplaceBench() | |
{ | |
return RTReplace(_string, '/', 'X'); | |
} | |
[Benchmark] | |
public string NewReplaceBench() | |
{ | |
return NewReplace(_string, '/', 'X'); | |
} | |
public string ClrReplace(string str, char oldChar, char newChar) | |
{ | |
return _string.Replace(oldChar, newChar); | |
} | |
public string RTReplace(string str, char oldChar, char newChar) | |
{ | |
// .net 4.6.1 does not have this if | |
//if (oldChar == newChar) | |
// return str; | |
unsafe | |
{ | |
int firstFoundIndex = -1; | |
fixed (char* pChars = str) | |
{ | |
for (int i = 0; i < str.Length; i++) | |
{ | |
if (oldChar == pChars[i]) | |
{ | |
firstFoundIndex = i; | |
break; | |
} | |
} | |
} | |
if (-1 == firstFoundIndex) | |
return str; | |
string result = new string('\0', str.Length); | |
fixed (char* pChars = str) | |
{ | |
fixed (char* pResult = result) | |
{ | |
//Copy the characters, doing the replacement as we go. | |
for (int i = 0; i < firstFoundIndex; i++) | |
pResult[i] = pChars[i]; | |
for (int i = firstFoundIndex; i < str.Length; i++) | |
pResult[i] = (pChars[i] == oldChar) ? newChar : pChars[i]; | |
} | |
} | |
return result; | |
} | |
} | |
public string NewReplace(string str, char oldChar, char newChar) | |
{ | |
// .net 4.6.1 does not have this if | |
//if (oldChar == newChar) | |
// return str; | |
unsafe | |
{ | |
//int currentIndex = -1; | |
int remainingLength = str.Length; | |
char* pSrc; | |
char* pDst; | |
fixed (char* pChars = str) | |
{ | |
pSrc = pChars; | |
while (remainingLength > 0) | |
{ | |
if (*pSrc == oldChar) | |
{ | |
break; | |
} | |
remainingLength--; | |
pSrc++; | |
} | |
} | |
if (remainingLength == 0) | |
return str; | |
string result = new string('\0', str.Length); | |
fixed (char* pChars = str) | |
{ | |
fixed (char* pResult = result) | |
{ | |
//Copy the characters, doing the replacement as we go. | |
pSrc = pChars; | |
pDst = pResult; | |
int copyLength = str.Length; | |
while (copyLength > remainingLength) | |
{ | |
*(int*)pDst = *(int*)pSrc; | |
copyLength -= 2; | |
pSrc+=2; | |
pDst+=2; | |
} | |
pSrc = pChars + (str.Length - remainingLength); | |
pDst = pResult + (str.Length - remainingLength); | |
do | |
{ | |
char currentChar = *pSrc; | |
if (currentChar == oldChar) | |
currentChar = newChar; | |
*pDst = currentChar; | |
remainingLength--; | |
pSrc++; | |
pDst++; | |
} while (remainingLength > 0); | |
} | |
} | |
return result; | |
} | |
} | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment