by Mwwhited
17. June 2009 23:06
In coming across this question on StackOverflow I inspired to write my own version for the question. I started to think about using a List<string> but decided to create sized array up front. My version was taking longer than I hoped (mainly because I kept refreshing the site) but I did create a version that used string.Join and Array.Copy. Wanting to compare the speed differences between a few of the answers I put together this little test of code.
(as a side note I did find a crazy speed difference between string.Join and StringBuilder. )
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
using System.IO;
using System.Text.RegularExpressions;
namespace stringChop
{
class Program
{
//http://stackoverflow.com/questions/1009839/net-split-by-length
static void Main(string[] args)
{
string chopMe = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
int partLength = 12;
Stopwatch sw = new Stopwatch();
//version 1 (my version)
{
sw = Stopwatch.StartNew();
char[] chopMeArray = chopMe.ToCharArray();
int totalLength = chopMe.Length;
int partCount = (totalLength / partLength) + ((totalLength % partLength == 0) ? 0 : 1);
int posIndex = 0;
char[] part = new char[partLength];
string[] parts = new string[partCount];
int get = partLength;
for (int i = 0; i < partCount; i++)
{
get = Math.Min(partLength, totalLength - posIndex);
Array.Copy(chopMeArray, posIndex, part, 0, get);
parts[i] = new string(part, 0, get);
posIndex += partLength;
}
var output = string.Join("\r\n", parts) + "\r\n";
sw.Stop();
Console.WriteLine(sw.ElapsedTicks); //203
}
//version 2 (based on Aric TenEyck's version)
{
var s = chopMe;
var len = partLength;
sw = Stopwatch.StartNew();
List output = new List();
while (s.Length > len)
{
output.Add(s.Substring(0, len) + "\n");
s = s.Remove(0, len);
}
output.Add(s + "\n");
var parts = string.Join("\r", output.ToArray());
sw.Stop();
Console.WriteLine(sw.ElapsedTicks); //266
}
//version 3 (My version with string builder instead of string.Join inspired by Robert Harvey)
{
sw = Stopwatch.StartNew();
StringBuilder sb = new StringBuilder();
char[] chopMeArray = chopMe.ToCharArray();
int totalLength = chopMe.Length;
int partCount = (totalLength / partLength) + ((totalLength % partLength == 0) ? 0 : 1);
int posIndex = 0;
char[] part = new char[partLength];
string[] parts = new string[partCount];
int get = partLength;
for (int i = 0; i < partCount; i++)
{
get = Math.Min(partLength, totalLength - posIndex);
Array.Copy(chopMeArray, posIndex, part, 0, get);
sb.AppendLine(new string(part, 0, get));
}
sw.Stop();
Console.WriteLine(sw.ElapsedTicks); //98
}
//version 4 (based on Joel Coehoorn's code)
{
sw = Stopwatch.StartNew();
List parts = new List();
var s = chopMe;
int length = partLength;
var buf = new char[length];
using (var rdr = new StringReader(s))
{
int l;
l = rdr.ReadBlock(buf, 0, length);
while (l > 0)
{
parts.Add(new string(buf, 0, l));
l = rdr.ReadBlock(buf, 0, length);
}
}
var outparts = string.Join("\r", parts.ToArray());
sw.Stop();
Console.WriteLine(sw.ElapsedTicks); //959
}
{ //version 5 (Fredou's)
sw = Stopwatch.StartNew();
string s = chopMe;
List a = new List();
for (int i = 0; i <= 7000; i++)
{
s += "a";
} for (int i = 0; i <= s.Length; i += 76)
{
if ((i + 76) > s.Length) { a.Add(s.Substring(i) + "\r\n"); }
else { a.Add(s.Substring(i, 76) + "\r\n"); }
}
var outparts = string.Join("\r", a.ToArray());
sw.Stop();
Console.WriteLine(sw.ElapsedTicks); //268765
}
{ //version 6 (Alan M's)
sw = Stopwatch.StartNew();
var outparts = Regex.Replace(chopMe, @"(?<=\G.{76})", "\r\n");
sw.Stop();
Console.WriteLine(sw.ElapsedTicks); //10661
}
Console.ReadLine();
}
}
}