Created
August 25, 2012 22:35
-
-
Save dtao/3471636 to your computer and use it in GitHub Desktop.
Proof of concept for an immutable string class optimized for concatenation with the + operator
This file contains 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 System; | |
using System.Text; | |
namespace FastStringConcatenation | |
{ | |
public class FastString | |
{ | |
const int DefaultCapacity = 32; | |
readonly StringBuilder buffer; | |
readonly int length; | |
string value; | |
private FastString(StringBuilder buffer) | |
{ | |
this.buffer = buffer; | |
this.length = this.buffer.Length; | |
} | |
private FastString(string value) : this(new StringBuilder(value, Math.Max(value.Length * 2, DefaultCapacity))) | |
{ | |
this.value = value; | |
} | |
public FastString() : this(new StringBuilder(DefaultCapacity)) | |
{ } | |
private bool OwnsBuffer | |
{ | |
get { return this.buffer.Length == this.length; } | |
} | |
public override string ToString() | |
{ | |
return this.value ?? (this.value = this.buffer.ToString(0, this.length)); | |
} | |
public static implicit operator FastString(string value) | |
{ | |
return new FastString(value); | |
} | |
public static explicit operator string(FastString fastString) | |
{ | |
return fastString.ToString(); | |
} | |
public static FastString operator +(FastString x, string y) | |
{ | |
if (x.OwnsBuffer) | |
{ | |
x.buffer.Append(y); | |
return new FastString(x.buffer); | |
} | |
else | |
{ | |
return new FastString(x.ToString() + y); | |
} | |
} | |
} | |
} |
This file contains 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 System; | |
using System.Collections.Generic; | |
using System.Diagnostics; | |
namespace FastStringConcatenation | |
{ | |
class FastStringDemo | |
{ | |
const int RandomStringCount = 20000; | |
const int RandomStringLength = 10; | |
public static void Main(string[] args) | |
{ | |
IList<string> strings = GetRandomStrings(RandomStringCount); | |
Console.WriteLine("Output equal? {0}", ConcatenateFast(strings) == Concatenate(strings)); | |
Console.ReadLine(); | |
} | |
static string ConcatenateFast(IList<string> strings) | |
{ | |
GC.Collect(); | |
Stopwatch sw = Stopwatch.StartNew(); | |
FastString fs = ""; | |
for (int i = 0; i < strings.Count; ++i) | |
{ | |
fs += strings[i]; | |
} | |
var result = (string)fs; | |
sw.Stop(); | |
Console.WriteLine("Finished concatenating {0} strings the 'fast' way in {1} ms.", strings.Count, sw.Elapsed.TotalMilliseconds); | |
return result; | |
} | |
static string Concatenate(IList<string> strings) | |
{ | |
GC.Collect(); | |
Stopwatch sw = Stopwatch.StartNew(); | |
string s = ""; | |
for (int i = 0; i < strings.Count; ++i) | |
{ | |
s += strings[i]; | |
} | |
sw.Stop(); | |
Console.WriteLine("Finished concatenating {0} strings the 'slow' way in {1} ms.", strings.Count, sw.Elapsed.TotalMilliseconds); | |
return s; | |
} | |
static IList<string> GetRandomStrings(int count) | |
{ | |
var strings = new List<string>(count); | |
var random = new Random(); | |
for (int i = 0; i < count; i++) | |
{ | |
strings.Add(GetRandomString(random, RandomStringLength)); | |
} | |
return strings; | |
} | |
static string GetRandomString(Random random, int length) | |
{ | |
var chars = new char[length]; | |
for (int i = 0; i < chars.Length; i++) | |
{ | |
chars[i] = (char)random.Next(1, 256); | |
} | |
return new string(chars); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment