surprisingly (unless i'm doing something wrong in my test)
the regex solution takes twice as long as my loop solution
Time for function :
RegexVersion
293 milliseconds
Time for function :
LoopVersion
111 milliseconds
public void CompareTimingMethods()
{
int NumTests = 10000;
List<string> oldList = new List<string>();
oldList.Add("this has some white space");
oldList.Add("this also has some white space");
List<string> newList2 =null ;
List<string> newList=null ;
Profile.StartTiming("RegexVersion");
for (int idx = 0; idx< NumTests; idx++)
{ newList2 =
RemoveExcessWhitespaceFromListOfStrings2(oldList); }
Profile.StopTiming("RegexVersion");
Profile.StartTiming("LoopVersion");
for (int idx = 0; idx< NumTests; idx++)
{newList = RemoveExcessWhitespaceFromListOfStrings(oldList);}
Profile.StopTiming("LoopVersion");
Profile.Report( );
}
the respective functions above call these two routines for each element in
oldList
regex version
private string RemoveExcessWhitespace2(string inputString)
{
string rep = @"\s+";
return Regex.Replace(inputString, rep, " ");
}
loop version
private string RemoveExcessWhitespace(string inputString)
{
StringBuilder sb = new StringBuilder();
sb.Append(inputString);
int lastLength = 0;
int thisLength = 0;
sb.Replace('\t', ' ');
do
{
lastLength = sb.Length;
sb.Replace(" ", " ");
thisLength = sb.Length;
} while (thisLength != lastLength);
sb.Replace(") ", ")");
sb.Replace(" (", "(");
return sb.ToString();
}
the regex version is probably not doing:
sb.Replace(") ", ")");
sb.Replace(" (", "(");
but that's a simple matter to add, what i'm really timing is if the loop
version is more costly...it doesn't seem to be
maybe if i add more spaces in the timing comparisons would change...i'll try
that too
First:
* if you are a student and having fun with this, then just continue
* if you are being paid for this, then start by testing whether
performance is really a problem, if not then stop wasting time on it
Second, regarding the testing then look below for some test code.
Arne
====
using System;
using System.Text;
using System.Text.RegularExpressions;
namespace E
{
public interface MultiSpaceTrimmerTest
{
string Trim(string s);
string Name { get; }
}
public class WhileString : MultiSpaceTrimmerTest
{
public string Trim(string s)
{
string res = s;
int len;
do
{
len = res.Length;
res = res.Replace(" ", " ");
}
while(res.Length < len);
return res;
}
public string Name
{
get
{
return "while loop with String";
}
}
}
public class WhileStringBuilder : MultiSpaceTrimmerTest
{
public string Trim(string s)
{
StringBuilder res = new StringBuilder(s);
int len;
do
{
len = res.Length;
res.Replace(" ", " ");
}
while(res.Length < len);
return res.ToString();
}
public string Name
{
get
{
return "while loop with StringBuilder";
}
}
}
public class RegexNegativeLookBehind : MultiSpaceTrimmerTest
{
public string Trim(string s)
{
return Regex.Replace(s, "(?<= ) ", "");
}
public string Name
{
get
{
return "static Regex Replace with ?<=";
}
}
}
public class RegexOneOrMore : MultiSpaceTrimmerTest
{
public string Trim(string s)
{
return Regex.Replace(s, " +", " ");
}
public string Name
{
get
{
return "static Regex Replace with +";
}
}
}
public class RegexNegativeLookBehindOpt : MultiSpaceTrimmerTest
{
private readonly Regex re = new Regex("(?<= ) ",
RegexOptions.Compiled);
public string Trim(string s)
{
return re.Replace(s, "");
}
public string Name
{
get
{
return "reused Regex Replace with ?<=";
}
}
}
public class RegexOneOrMoreOpt : MultiSpaceTrimmerTest
{
private readonly Regex re = new Regex(" +", RegexOptions.Compiled);
public string Trim(string s)
{
return re.Replace(s, " ");
}
public string Name
{
get
{
return "reused Regex Replace with +";
}
}
}
public class ForLoop : MultiSpaceTrimmerTest
{
public string Trim(string s)
{
StringBuilder res = new StringBuilder();
res.Append(s[0]);
for(int i = 1; i < s.Length; i++)
{
if(s
!= ' ' || s[i-1] != ' ')
{
res.Append(s);
}
}
return res.ToString();
}
public string Name
{
get
{
return "for loop";
}
}
}
public class Program
{
private const string BASE = "x x x x x";
private const int N = 10000000;
private static void FuncTest()
{
Console.WriteLine(new WhileString().Trim(BASE));
Console.WriteLine(new WhileStringBuilder().Trim(BASE));
Console.WriteLine(new RegexNegativeLookBehind().Trim(BASE));
Console.WriteLine(new RegexOneOrMore().Trim(BASE));
Console.WriteLine(new RegexNegativeLookBehindOpt().Trim(BASE));
Console.WriteLine(new RegexOneOrMoreOpt().Trim(BASE));
Console.WriteLine(new ForLoop().Trim(BASE));
}
private static void PerfTest(string s, MultiSpaceTrimmerTest mstt)
{
long t1 = DateTime.Now.Ticks;
for(int i = 0; i < N/s.Length; i++)
{
mstt.Trim(s);
}
long t2 = DateTime.Now.Ticks;
Console.WriteLine(" {0} : {1}", mstt.Name, s.Length*(t2 -
t1)/N);
}
private static void PerfTest(string s)
{
Console.WriteLine("string with length {0}:", s.Length);
PerfTest(s, new WhileString());
PerfTest(s, new WhileStringBuilder());
PerfTest(s, new RegexNegativeLookBehind());
PerfTest(s, new RegexOneOrMore());
PerfTest(s, new RegexNegativeLookBehindOpt());
PerfTest(s, new RegexOneOrMoreOpt());
PerfTest(s, new ForLoop());
}
private static void PerfTest(int n)
{
StringBuilder data = new StringBuilder();
for(int i = 0; i < n; i++)
{
data.Append(BASE);
}
PerfTest(data.ToString());
}
private static void PerfTest()
{
PerfTest(1);
PerfTest(10);
PerfTest(100);
}
public static void Main(string[] args)
{
FuncTest();
PerfTest();
Console.ReadKey();
}
}
}