Question Background
I read this question that is about how to reverse a string as fast as possible. I found that one of the answers was comparing different methods. In one of them, they just run a loop swapping elements from position i
with the one at position string.Length-1-i
but they use the known tricky swap via XOR. I was wondering how faster is reversing the string using the swap via XOR in comparison with the same method using the classic swap via a temporal variable. Surprisingly I'm getting almost a 50% improvement over the XOR one.
The Question
Is the compiler doing something magic behind the scenes, why I'm I getting this result?
The modified code with the Benchmarks
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ContestLibrary
{
public class Problem
{
delegate string StringDelegate(string s);
static void Benchmark(string description, StringDelegate d, int times, string text)
{
Stopwatch sw = new Stopwatch();
sw.Start();
for (int j = 0; j < times; j++)
{
d(text);
}
sw.Stop();
Console.WriteLine("{0} Ticks {1} : called {2} times.", sw.ElapsedTicks, description, times);
}
public static string ReverseXor(string s)
{
char[] charArray = s.ToCharArray();
int len = s.Length - 1;
for (int i = 0; i < len; i++, len--)
{
charArray[i] ^= charArray[len];
charArray[len] ^= charArray[i];
charArray[i] ^= charArray[len];
}
return new string(charArray);
}
public static string ReverseClassic(string s)
{
char[] charArray = s.ToCharArray();
int len = s.Length-1;
for (int i = 0; i < len; i++, len--)
{
char temp = charArray[len];
charArray[len] = charArray[i];
charArray[i] = temp;
}
return new string(charArray);
}
public static string StringOfLength(int length)
{
Random random = new Random();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < length; i++)
{
sb.Append(Convert.ToChar(Convert.ToInt32(Math.Floor(26 * random.NextDouble() + 65))));
}
return sb.ToString();
}
static void Main(string[] args)
{
int[] lengths = new int[] {1,10,100,1000, 10000, 100000};
foreach (int l in lengths)
{
int iterations = 10000;
string text = StringOfLength(l);
Benchmark(String.Format("Classic (Length: {0})", l), ReverseClassic, iterations, text);
Benchmark(String.Format("Xor (Length: {0})", l), ReverseXor, iterations, text);
Console.WriteLine();
}
Console.Read();
}
}
}