-
-
Save meritozh/b7a593dac2f05d20df49 to your computer and use it in GitHub Desktop.
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.Globalization; | |
using System.IO; | |
namespace TestStringFormatPerformance | |
{ | |
public class CorrectnessTester<T> where T : ITextWriterUtils, new() | |
{ | |
public void Test() | |
{ | |
Test(0); | |
Test(int.MinValue); | |
Test(int.MaxValue); | |
Test("1234567890", 1); | |
Test("-1234567890", 2); | |
} | |
private void Test(string test, int startFrom) | |
{ | |
for (var i = startFrom; i < test.Length; i++) | |
{ | |
Test(int.Parse(test.Substring(0, i))); | |
} | |
} | |
public void Test(int number) | |
{ | |
var correctString = number.ToString(CultureInfo.InvariantCulture); | |
var writer = new StringWriter(); | |
var writerAdapter = new TextWriterAdapter(writer); | |
var util = new T(); | |
util.Write(writerAdapter, number); | |
var utilString = writer.ToString(); | |
var correct = correctString == utilString; | |
Console.WriteLine( | |
"[" + typeof(T).Name + "] " + correctString + " is " + | |
(correct | |
? "correct" | |
: ("in correct (" + utilString + ")") | |
) | |
); | |
} | |
} | |
} |
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.Globalization; | |
using System.IO; | |
using System.Linq; | |
namespace TestStringFormatPerformance | |
{ | |
public class ExtremeTextWriterUtils : ITextWriterUtils | |
{ | |
private static readonly string[] _zeroPaddingStrings; | |
private static readonly string[] _nonZeroPaddingStrings; | |
private static readonly string _minString; | |
static ExtremeTextWriterUtils() | |
{ | |
_zeroPaddingStrings = Enumerable.Range(0, 10000).Select(i => i.ToString("0000", CultureInfo.InvariantCulture)).ToArray(); | |
_nonZeroPaddingStrings = Enumerable.Range(0, 10000).Select(i => i.ToString(CultureInfo.InvariantCulture)).ToArray(); | |
_minString = int.MinValue.ToString(CultureInfo.InvariantCulture); | |
} | |
[ThreadStatic] | |
private static char[] _buffer; | |
private static char[] GetBuffer() | |
{ | |
if (_buffer == null) | |
{ | |
_buffer = new char[11]; | |
_buffer[0] = '-'; | |
} | |
return _buffer; | |
} | |
private static void WriteCore(ITextWriter writer, int start, int value) | |
{ | |
var buffer = GetBuffer(); | |
var high = value / 100000000; | |
int offset; | |
if (high > 0) | |
{ | |
offset = CopyToBuffer(buffer, 1, _nonZeroPaddingStrings[high]); | |
value -= high * 100000000; | |
high = value / 10000; | |
offset = CopyToBuffer(buffer, offset, _zeroPaddingStrings[high]); | |
value -= high * 10000; | |
offset = CopyToBuffer(buffer, offset, _zeroPaddingStrings[value]); | |
} | |
else | |
{ | |
high = value / 10000; | |
if (high > 0) | |
{ | |
offset = CopyToBuffer(buffer, 1, _nonZeroPaddingStrings[high]); | |
value -= high * 10000; | |
offset = CopyToBuffer(buffer, offset, _zeroPaddingStrings[value]); | |
} | |
else | |
{ | |
offset = CopyToBuffer(buffer, 1, _nonZeroPaddingStrings[value]); | |
} | |
} | |
writer.Write(buffer, start, offset - start); | |
} | |
private static int CopyToBuffer(char[] buffer, int offset, string s) | |
{ | |
for (int i = 0; i < s.Length; i++) | |
{ | |
buffer[offset++] = s[i]; | |
} | |
return offset; | |
} | |
public void Write(ITextWriter writer, int value) | |
{ | |
if (value == int.MinValue) { writer.Write(_minString); return; } | |
if (value < 0) { WriteCore(writer, 0, -value); return; } | |
if (value <= 9999) | |
{ | |
writer.Write(_nonZeroPaddingStrings[value]); | |
return; | |
} | |
WriteCore(writer, 1, value); | |
} | |
} | |
} |
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; | |
namespace TestStringFormatPerformance | |
{ | |
public class HentaiTextWriterUtils : ITextWriterUtils | |
{ | |
private readonly static char[] Map = new[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' }; | |
public void Write(ITextWriter writer, int value) | |
{ | |
var i = value; | |
var result = new char[11]; | |
var p = 10; | |
var neg = value < 0; | |
do | |
{ | |
var q = 0; | |
i = Math.DivRem(i, 10, out q); | |
result[p--] = neg ? Map[-q] : Map[q]; | |
} while (i != 0); | |
if (neg) | |
result[p--] = '-'; | |
writer.Write(result, p + 1, 10 - p); | |
} | |
} | |
} |
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
namespace TestStringFormatPerformance | |
{ | |
public interface ITextWriter | |
{ | |
void Write(string text); | |
void Write(string text, int startIndex, int count); | |
void Write(char[] chars); | |
void Write(char[] chars, int startIndex, int count); | |
} | |
} |
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
namespace TestStringFormatPerformance | |
{ | |
public interface ITextWriterUtils | |
{ | |
void Write(ITextWriter writer, int value); | |
} | |
} |
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.Concurrent; | |
using System.Collections.Generic; | |
using System.IO; | |
using System.Linq; | |
using System.Text; | |
using System.Threading.Tasks; | |
namespace TestStringFormatPerformance | |
{ | |
public class MTRSBTester<T> : MultiThreadRandomPerformanceTester<T> where T : ITextWriterUtils, new() | |
{ | |
public MTRSBTester(RandomSet randomSet) : base(randomSet) { } | |
private const int MAX_ROUND = 1000000; | |
private ConcurrentBag<StringBuilder> _stringBuilders = new ConcurrentBag<StringBuilder>(); | |
public override void Test(int round) | |
{ | |
GC.Collect(2, GCCollectionMode.Forced); | |
GC.WaitForFullGCComplete(); | |
for (int i = 0; i < Environment.ProcessorCount; i++) | |
{ | |
_stringBuilders.Add(new StringBuilder(800000)); | |
} | |
base.Test(round); | |
GC.Collect(2, GCCollectionMode.Forced); | |
GC.WaitForFullGCComplete(); | |
} | |
protected override string ExtraInfo | |
{ | |
get | |
{ | |
return ", sb, " + _randomSet.Name; | |
} | |
} | |
protected override void TestCore() | |
{ | |
StringBuilder stringBuilder; | |
_stringBuilders.TryTake(out stringBuilder); | |
var writer = new TextWriterAdapter(new StringWriter(stringBuilder)); | |
var util = new T(); | |
int end = _round / _threads.Length; | |
for (int i = 0; i < end;) | |
{ | |
util.Write(writer, _randomSet.Get(i)); | |
i++; | |
if ((i & 0xFFFF) == 0) stringBuilder.Length = 0; | |
} | |
} | |
} | |
} |
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.Diagnostics; | |
using System.IO; | |
using System.Linq; | |
using System.Threading; | |
namespace TestStringFormatPerformance | |
{ | |
public class MultiThreadPerformanceTester<T> where T : ITextWriterUtils, new() | |
{ | |
private const int _testValue = -1234567890; | |
protected Thread[] _threads = new Thread[Environment.ProcessorCount]; | |
protected int _round; | |
protected virtual string ExtraInfo { get { return null; } } | |
public virtual void Test(int round) | |
{ | |
_round = round; | |
for (int i = 0; i < _threads.Length; i++) | |
{ | |
_threads[i] = new Thread(TestCore); | |
} | |
var watch = new Stopwatch(); | |
watch.Start(); | |
for (int i = 0; i < _threads.Length; i++) | |
{ | |
_threads[i].Start(); | |
} | |
for (int i = 0; i < _threads.Length; i++) | |
{ | |
_threads[i].Join(); | |
} | |
watch.Stop(); | |
Console.WriteLine((round / watch.Elapsed.TotalSeconds) + " op/s [" + typeof(T).Name + "] Multi thread" + ExtraInfo); | |
} | |
protected virtual void TestCore() | |
{ | |
var writer = new TextWriterAdapter(TextWriter.Null); | |
var util = new T(); | |
int end = _round / _threads.Length; | |
for (int i = 0; i < end; i++) | |
{ | |
util.Write(writer, _testValue); | |
} | |
} | |
} | |
} |
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.Diagnostics; | |
using System.IO; | |
using System.Linq; | |
namespace TestStringFormatPerformance | |
{ | |
public class MultiThreadRandomPerformanceTester<T> : MultiThreadPerformanceTester<T> where T : ITextWriterUtils, new() | |
{ | |
public MultiThreadRandomPerformanceTester(RandomSet randomSet) | |
{ | |
_randomSet = randomSet; | |
} | |
protected readonly RandomSet _randomSet; | |
protected override void TestCore() | |
{ | |
var writer = new TextWriterAdapter(TextWriter.Null); | |
var util = new T(); | |
int end = _round / _threads.Length; | |
for (int i = 0; i < end ; i++) | |
{ | |
util.Write(writer, _randomSet.Get(i)); | |
} | |
} | |
protected override string ExtraInfo | |
{ | |
get | |
{ | |
return ", " + _randomSet.Name ; | |
} | |
} | |
} | |
} |
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; | |
namespace TestStringFormatPerformance | |
{ | |
class Program | |
{ | |
static void Main(string[] args) | |
{ | |
new CorrectnessTester<SampletTextWriterUtils>().Test(); | |
new CorrectnessTester<ThreadStaticTextWriterUtils>().Test(); | |
new CorrectnessTester<HentaiTextWriterUtils>().Test(); | |
new CorrectnessTester<ExtremeTextWriterUtils>().Test(); | |
int round = 10000000; | |
new SingleThreadPerformanceTester<SampletTextWriterUtils>().Test(round); | |
new SingleThreadPerformanceTester<ThreadStaticTextWriterUtils>().Test(round); | |
new SingleThreadPerformanceTester<HentaiTextWriterUtils>().Test(round); | |
new SingleThreadPerformanceTester<ExtremeTextWriterUtils>().Test(round); | |
Console.WriteLine("-------\n"); | |
new MultiThreadPerformanceTester<SampletTextWriterUtils>().Test(round); | |
new MultiThreadPerformanceTester<ThreadStaticTextWriterUtils>().Test(round); | |
new MultiThreadPerformanceTester<HentaiTextWriterUtils>().Test(round); | |
new MultiThreadPerformanceTester<ExtremeTextWriterUtils>().Test(round); | |
Console.WriteLine("-------\n"); | |
Test(round, RandomSet.SmallNumbers); | |
Test(round, RandomSet.LargeNumbers); | |
Console.WriteLine("DONE!"); | |
Console.ReadKey(); | |
} | |
private static void Test(int round, RandomSet randomSet) | |
{ | |
new SingleThreadRandomPerformanceTester<SampletTextWriterUtils>().Test(round, randomSet); | |
new SingleThreadRandomPerformanceTester<ThreadStaticTextWriterUtils>().Test(round, randomSet); | |
new SingleThreadRandomPerformanceTester<HentaiTextWriterUtils>().Test(round, randomSet); | |
new SingleThreadRandomPerformanceTester<ExtremeTextWriterUtils>().Test(round, randomSet); | |
Console.WriteLine("-------\n"); | |
new MultiThreadRandomPerformanceTester<SampletTextWriterUtils>(randomSet).Test(round); | |
new MultiThreadRandomPerformanceTester<ThreadStaticTextWriterUtils>(randomSet).Test(round); | |
new MultiThreadRandomPerformanceTester<HentaiTextWriterUtils>(randomSet).Test(round); | |
new MultiThreadRandomPerformanceTester<ExtremeTextWriterUtils>(randomSet).Test(round); | |
Console.WriteLine("-------\n"); | |
new MTRSBTester<SampletTextWriterUtils>(randomSet).Test(round); | |
new MTRSBTester<ThreadStaticTextWriterUtils>(randomSet).Test(round); | |
new MTRSBTester<HentaiTextWriterUtils>(randomSet).Test(round); | |
new MTRSBTester<ExtremeTextWriterUtils>(randomSet).Test(round); | |
Console.WriteLine("-------\n"); | |
} | |
} | |
} |
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.Linq; | |
using System.Text; | |
using System.Threading.Tasks; | |
namespace TestStringFormatPerformance | |
{ | |
public class RandomSet | |
{ | |
static RandomSet() | |
{ | |
LargeNumbers = new RandomSet(int.MinValue, int.MaxValue, "largeRnd"); | |
SmallNumbers = new RandomSet(-200000, 200000, "smallRnd"); | |
} | |
public RandomSet(int min, int max, string name) | |
{ | |
Name = name; | |
var rnd = new Random(); | |
_numbers = Enumerable.Repeat(0, 2<<20).Select(i => rnd.Next(min, max)).ToArray(); | |
} | |
private readonly int[] _numbers; | |
public int Get(int i) | |
{ | |
return _numbers[i & 0xFFFFF]; | |
} | |
public static RandomSet LargeNumbers{get;private set;} | |
public static RandomSet SmallNumbers { get; private set; } | |
public string Name { get; private set; } | |
} | |
} |
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
[SampletTextWriterUtils] 0 is correct | |
[SampletTextWriterUtils] -2147483648 is correct | |
[SampletTextWriterUtils] 2147483647 is correct | |
[SampletTextWriterUtils] 1 is correct | |
[SampletTextWriterUtils] 12 is correct | |
[SampletTextWriterUtils] 123 is correct | |
[SampletTextWriterUtils] 1234 is correct | |
[SampletTextWriterUtils] 12345 is correct | |
[SampletTextWriterUtils] 123456 is correct | |
[SampletTextWriterUtils] 1234567 is correct | |
[SampletTextWriterUtils] 12345678 is correct | |
[SampletTextWriterUtils] 123456789 is correct | |
[SampletTextWriterUtils] -1 is correct | |
[SampletTextWriterUtils] -12 is correct | |
[SampletTextWriterUtils] -123 is correct | |
[SampletTextWriterUtils] -1234 is correct | |
[SampletTextWriterUtils] -12345 is correct | |
[SampletTextWriterUtils] -123456 is correct | |
[SampletTextWriterUtils] -1234567 is correct | |
[SampletTextWriterUtils] -12345678 is correct | |
[SampletTextWriterUtils] -123456789 is correct | |
[ThreadStaticTextWriterUtils] 0 is correct | |
[ThreadStaticTextWriterUtils] -2147483648 is correct | |
[ThreadStaticTextWriterUtils] 2147483647 is correct | |
[ThreadStaticTextWriterUtils] 1 is correct | |
[ThreadStaticTextWriterUtils] 12 is correct | |
[ThreadStaticTextWriterUtils] 123 is correct | |
[ThreadStaticTextWriterUtils] 1234 is correct | |
[ThreadStaticTextWriterUtils] 12345 is correct | |
[ThreadStaticTextWriterUtils] 123456 is correct | |
[ThreadStaticTextWriterUtils] 1234567 is correct | |
[ThreadStaticTextWriterUtils] 12345678 is correct | |
[ThreadStaticTextWriterUtils] 123456789 is correct | |
[ThreadStaticTextWriterUtils] -1 is correct | |
[ThreadStaticTextWriterUtils] -12 is correct | |
[ThreadStaticTextWriterUtils] -123 is correct | |
[ThreadStaticTextWriterUtils] -1234 is correct | |
[ThreadStaticTextWriterUtils] -12345 is correct | |
[ThreadStaticTextWriterUtils] -123456 is correct | |
[ThreadStaticTextWriterUtils] -1234567 is correct | |
[ThreadStaticTextWriterUtils] -12345678 is correct | |
[ThreadStaticTextWriterUtils] -123456789 is correct | |
[HentaiTextWriterUtils] 0 is correct | |
[HentaiTextWriterUtils] -2147483648 is correct | |
[HentaiTextWriterUtils] 2147483647 is correct | |
[HentaiTextWriterUtils] 1 is correct | |
[HentaiTextWriterUtils] 12 is correct | |
[HentaiTextWriterUtils] 123 is correct | |
[HentaiTextWriterUtils] 1234 is correct | |
[HentaiTextWriterUtils] 12345 is correct | |
[HentaiTextWriterUtils] 123456 is correct | |
[HentaiTextWriterUtils] 1234567 is correct | |
[HentaiTextWriterUtils] 12345678 is correct | |
[HentaiTextWriterUtils] 123456789 is correct | |
[HentaiTextWriterUtils] -1 is correct | |
[HentaiTextWriterUtils] -12 is correct | |
[HentaiTextWriterUtils] -123 is correct | |
[HentaiTextWriterUtils] -1234 is correct | |
[HentaiTextWriterUtils] -12345 is correct | |
[HentaiTextWriterUtils] -123456 is correct | |
[HentaiTextWriterUtils] -1234567 is correct | |
[HentaiTextWriterUtils] -12345678 is correct | |
[HentaiTextWriterUtils] -123456789 is correct | |
[ExtremeTextWriterUtils] 0 is correct | |
[ExtremeTextWriterUtils] -2147483648 is correct | |
[ExtremeTextWriterUtils] 2147483647 is correct | |
[ExtremeTextWriterUtils] 1 is correct | |
[ExtremeTextWriterUtils] 12 is correct | |
[ExtremeTextWriterUtils] 123 is correct | |
[ExtremeTextWriterUtils] 1234 is correct | |
[ExtremeTextWriterUtils] 12345 is correct | |
[ExtremeTextWriterUtils] 123456 is correct | |
[ExtremeTextWriterUtils] 1234567 is correct | |
[ExtremeTextWriterUtils] 12345678 is correct | |
[ExtremeTextWriterUtils] 123456789 is correct | |
[ExtremeTextWriterUtils] -1 is correct | |
[ExtremeTextWriterUtils] -12 is correct | |
[ExtremeTextWriterUtils] -123 is correct | |
[ExtremeTextWriterUtils] -1234 is correct | |
[ExtremeTextWriterUtils] -12345 is correct | |
[ExtremeTextWriterUtils] -123456 is correct | |
[ExtremeTextWriterUtils] -1234567 is correct | |
[ExtremeTextWriterUtils] -12345678 is correct | |
[ExtremeTextWriterUtils] -123456789 is correct | |
6605147.64255345 op/s [SampletTextWriterUtils] Single thread | |
8903163.23157404 op/s [ThreadStaticTextWriterUtils] Single thread | |
8716228.53672304 op/s [HentaiTextWriterUtils] Single thread | |
19648805.1168632 op/s [ExtremeTextWriterUtils] Single thread | |
------- | |
30720173.0160144 op/s [SampletTextWriterUtils] Multi thread | |
47360885.686451 op/s [ThreadStaticTextWriterUtils] Multi thread | |
44341080.4591075 op/s [HentaiTextWriterUtils] Multi thread | |
80020869.4427507 op/s [ExtremeTextWriterUtils] Multi thread | |
------- | |
7904069.88462429 op/s [SampletTextWriterUtils] Single thread, smallRnd | |
12246765.9658945 op/s [ThreadStaticTextWriterUtils] Single thread, smallRnd | |
13137032.7830712 op/s [HentaiTextWriterUtils] Single thread, smallRnd | |
17222609.6352579 op/s [ExtremeTextWriterUtils] Single thread, smallRnd | |
------- | |
33681850.6694941 op/s [SampletTextWriterUtils] Multi thread, smallRnd | |
63245346.4074113 op/s [ThreadStaticTextWriterUtils] Multi thread, smallRnd | |
60807055.5642712 op/s [HentaiTextWriterUtils] Multi thread, smallRnd | |
83077178.6990114 op/s [ExtremeTextWriterUtils] Multi thread, smallRnd | |
------- | |
27854183.3501619 op/s [SampletTextWriterUtils] Multi thread, sb, smallRnd | |
40513221.4898332 op/s [ThreadStaticTextWriterUtils] Multi thread, sb, smallRnd | |
37577018.7971521 op/s [HentaiTextWriterUtils] Multi thread, sb, smallRnd | |
47022289.9761174 op/s [ExtremeTextWriterUtils] Multi thread, sb, smallRnd | |
------- | |
6187943.818668 op/s [SampletTextWriterUtils] Single thread, largeRnd | |
7710310.08014328 op/s [ThreadStaticTextWriterUtils] Single thread, largeRnd | |
8233501.44222128 op/s [HentaiTextWriterUtils] Single thread, largeRnd | |
13942371.4384386 op/s [ExtremeTextWriterUtils] Single thread, largeRnd | |
------- | |
29246342.2330928 op/s [SampletTextWriterUtils] Multi thread, largeRnd | |
45563774.2479016 op/s [ThreadStaticTextWriterUtils] Multi thread, largeRnd | |
43212111.8364024 op/s [HentaiTextWriterUtils] Multi thread, largeRnd | |
62966661.6713115 op/s [ExtremeTextWriterUtils] Multi thread, largeRnd | |
------- | |
23357969.762641 op/s [SampletTextWriterUtils] Multi thread, sb, largeRnd | |
32218197.0954651 op/s [ThreadStaticTextWriterUtils] Multi thread, sb, largeRnd | |
30974971.2939454 op/s [HentaiTextWriterUtils] Multi thread, sb, largeRnd | |
40769267.1479615 op/s [ExtremeTextWriterUtils] Multi thread, sb, largeRnd | |
------- | |
DONE! |
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.Globalization; | |
namespace TestStringFormatPerformance | |
{ | |
public class SampletTextWriterUtils : ITextWriterUtils | |
{ | |
public void Write(ITextWriter writer, int value) | |
{ | |
writer.Write(value.ToString(CultureInfo.InvariantCulture)); | |
} | |
} | |
} |
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.Diagnostics; | |
using System.IO; | |
namespace TestStringFormatPerformance | |
{ | |
public class SingleThreadPerformanceTester<T> where T : ITextWriterUtils, new() | |
{ | |
private const int _testValue = -1234567890; | |
public void Test(int round) | |
{ | |
var writer = new TextWriterAdapter(TextWriter.Null); | |
var util = new T(); | |
// Cold start; | |
util.Write(writer, _testValue); | |
var watch = new Stopwatch(); | |
watch.Start(); | |
for (int i = 0; i < round; i++) | |
{ | |
util.Write(writer, _testValue); | |
} | |
watch.Stop(); | |
Console.WriteLine((round / watch.Elapsed.TotalSeconds) + " op/s [" + typeof(T).Name + "] Single thread"); | |
} | |
} | |
} |
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; | |
using System.IO; | |
using System.Linq; | |
using System.Text; | |
using System.Threading.Tasks; | |
namespace TestStringFormatPerformance | |
{ | |
public class SingleThreadRandomPerformanceTester<T> where T : ITextWriterUtils, new() | |
{ | |
public void Test(int round, RandomSet randomSet) | |
{ | |
var writer = new TextWriterAdapter(TextWriter.Null); | |
var util = new T(); | |
// Cold start; | |
util.Write(writer, 0); | |
var watch = new Stopwatch(); | |
watch.Start(); | |
for (int i = 0; i < round; i++) | |
{ | |
util.Write(writer, randomSet.Get(i)); | |
} | |
watch.Stop(); | |
Console.WriteLine((round / watch.Elapsed.TotalSeconds) + " op/s [" + typeof(T).Name + "] Single thread, " + randomSet.Name); | |
} | |
} | |
} |
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.IO; | |
namespace TestStringFormatPerformance | |
{ | |
public class TextWriterAdapter : ITextWriter | |
{ | |
public TextWriterAdapter(TextWriter writer) | |
{ | |
_writer = writer; | |
} | |
private TextWriter _writer; | |
public void Write(char[] chars) | |
{ | |
_writer.Write(chars); | |
} | |
public void Write(string text) | |
{ | |
_writer.Write(text); | |
} | |
public void Write(char[] chars, int startIndex, int count) | |
{ | |
_writer.Write(chars, startIndex, count); | |
} | |
public void Write(string text, int startIndex, int count) | |
{ | |
_writer.Write(text.Substring(startIndex, count)); | |
} | |
} | |
} |
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.Globalization; | |
namespace TestStringFormatPerformance | |
{ | |
public class ThreadStaticTextWriterUtils :ITextWriterUtils | |
{ | |
[ThreadStatic] | |
private static char[] _buffer; | |
private static readonly string _intMinString = int.MinValue.ToString(CultureInfo.InvariantCulture); | |
public void Write(ITextWriter writer, int value) | |
{ | |
char[] buffer = GetBuffer(); | |
if (value == 0) { writer.Write("0"); return; } | |
if (value == int.MinValue) { writer.Write(_intMinString); return; } | |
bool negative = value < 0; | |
if (negative) value = -value; | |
int i = 11; | |
while (value != 0) | |
{ | |
i--; | |
buffer[i] = (char)((value % 10) + '0'); | |
value /= 10; | |
} | |
if (negative) | |
{ | |
buffer[--i] = '-'; | |
} | |
writer.Write(buffer, i, 11 - i); | |
} | |
private char[] GetBuffer() | |
{ | |
if (_buffer == null) | |
{ | |
_buffer = new char[11]; | |
} | |
return _buffer; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment