Skip to content

Instantly share code, notes, and snippets.

@ReubenBond
Created December 15, 2016 04:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ReubenBond/01ab8cea36997bbb97bdc45ad15c54a5 to your computer and use it in GitHub Desktop.
Save ReubenBond/01ab8cea36997bbb97bdc45ad15c54a5 to your computer and use it in GitHub Desktop.
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using OrleansBenchmarks.Serialization;
namespace OrleansBenchmarks
{
using BenchmarkDotNet.Attributes;
[Config(typeof(SerializationBenchmarkConfig))]
public class PoolBenchmark
{
private readonly ConcurrentBag<StringBuilder> concurrentBag = new ConcurrentBag<StringBuilder>();
private readonly ThreadLocal<List<StringBuilder>> stackPool = new ThreadLocal<List<StringBuilder>>(() => new List<StringBuilder>());
[ThreadStatic]
private static List<StringBuilder> tsPool;
private static List<StringBuilder> GetThreadStaticPool() => tsPool ?? (tsPool = new List<StringBuilder>());
[Setup]
public void Setup()
{
ReturnListPool(GetListPool());
ReturnBag(GetBag());
ReturnThreadStaticListPool(GetThreadStaticListPool());
}
private StringBuilder GetListPool()
{
var pool = stackPool.Value;
if (pool.Count > 0)
{
var val = pool[pool.Count - 1];
pool.RemoveAt(pool.Count - 1);
return val;
}
return new StringBuilder();
}
private void ReturnListPool(StringBuilder value)
{
stackPool.Value.Add(value);
}
private StringBuilder GetThreadStaticListPool()
{
var pool = GetThreadStaticPool();
if (pool.Count > 0)
{
var last = pool.Count - 1;
var val = pool[last];
pool.RemoveAt(last);
return val;
}
return new StringBuilder();
}
private void ReturnThreadStaticListPool(StringBuilder value)
{
GetThreadStaticPool().Add(value);
}
private StringBuilder GetBag()
{
StringBuilder result;
if (concurrentBag.TryTake(out result)) return result;
return new StringBuilder();
}
private void ReturnBag(StringBuilder value)
{
concurrentBag.Add(value);
}
[Benchmark]
public void ConcurrentBagPool()
{
var val = GetBag();
ReturnBag(val);
}
[Benchmark]
public void ThreadLocalListPool()
{
var val = GetListPool();
ReturnListPool(val);
}
[Benchmark]
public void ThreadStaticListPool()
{
var val = GetThreadStaticListPool();
ReturnThreadStaticListPool(val);
}
}
}
@ReubenBond
Copy link
Author

// * Summary *

Host Process Environment Information:
BenchmarkDotNet.Core=v0.9.9.0
OS=Microsoft Windows NT 6.2.9200.0
Processor=Intel(R) Xeon(R) CPU E3-1230 v5 3.40GHz, ProcessorCount=8
Frequency=3328121 ticks, Resolution=300.4698 ns, Timer=TSC
CLR=MS.NET 4.0.30319.42000, Arch=32-bit RELEASE
GC=Non-concurrent Server
JitModules=clrjit-v4.6.2012.0

Type=PoolBenchmark  Mode=Throughput

               Method |      Median |    StdDev | Gen 0 | Gen 1 | Gen 2 | Bytes Allocated/Op |
--------------------- |------------ |---------- |------ |------ |------ |------------------- |
    ConcurrentBagPool | 135.7436 ns | 1.6784 ns | 17.00 |     - |     - |               8.02 |
  ThreadLocalListPool |  41.3818 ns | 0.4723 ns |     - |     - |     - |               0.00 |
 ThreadStaticListPool |  32.8183 ns | 0.8218 ns |     - |     - |     - |               0.00 |

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment