Skip to content

Commit 5019273

Browse files
author
Oren (electricessence)
committed
Reformat and contract improvments.
1 parent a2cd015 commit 5019273

10 files changed

Lines changed: 204 additions & 203 deletions

benchmarking/Benchmark.cs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,14 @@
11
using Open.Diagnostics;
22
using System;
3-
using System.Collections.Concurrent;
43
using System.Collections.Generic;
5-
using System.Diagnostics;
6-
using System.Linq;
74
using System.Threading.Tasks;
85

96
namespace Open.Disposable.ObjectPools
107
{
118
public class Benchmark<T> : BenchmarkBase<Func<IObjectPool<T>>>
129
where T : class
1310
{
14-
public Benchmark(uint size, uint repeat, Func<IObjectPool<T>> poolFactory) : base(size,repeat,poolFactory)
11+
public Benchmark(uint size, uint repeat, Func<IObjectPool<T>> poolFactory) : base(size, repeat, poolFactory)
1512
{
1613
// Because some pools do comparison checks on values, we have have unique instances/values.
1714
_items = new T[(int)size];
@@ -47,7 +44,8 @@ protected override IEnumerable<TimedResult> TestOnceInternal()
4744

4845
yield return TimedResult.Measure("Empty Pool (.TryTake())", () =>
4946
{
50-
while (pool.TryTake() != null) {
47+
while (pool.TryTake() != null)
48+
{
5149
// remaining++;
5250
}
5351
});

benchmarking/ConsoleReport.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,14 @@ namespace Open.Disposable.ObjectPools
66
{
77
public class ConsoleReport<T> : Open.Diagnostics.BenchmarkConsoleReport<Func<IObjectPool<T>>>
88
where T : class
9-
{
9+
{
1010
const int ITERATIONS = 100000;
11-
public ConsoleReport(TextWriter output = null) : base(ITERATIONS, output, (c,r,p)=> Benchmark<T>.Results(c, r, p))
11+
public ConsoleReport(TextWriter output = null) : base(ITERATIONS, output, (c, r, p) => Benchmark<T>.Results(c, r, p))
1212
{
1313
}
1414

15-
public ConsoleReport(StringBuilder output) : this (new StringWriter(output))
15+
public ConsoleReport(StringBuilder output) : this(new StringWriter(output))
1616
{
17-
}
17+
}
1818
}
1919
}

benchmarking/Program.cs

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -21,32 +21,32 @@ static void Main(string[] args)
2121
* 3) A sync locked Queue is faster than a sync locked LinkedList.
2222
* 4) ConcurrentQueue seems to be the overall winner when dealing with pools larger than 100 but is the clear loser for very small sizes.
2323
*/
24-
24+
2525
// Start with a baseline...
2626
report.AddBenchmark("QueueObjectPool", // Note, that this one isn't far off from the following in peformance.
2727
count => () => QueueObjectPool.Create<object>((int)count * 2));
2828

29-
//report.AddBenchmark("ChannelObjectPool",
30-
// count => () => ChannelObjectPool.Create<object>((int)count * 2));
29+
//report.AddBenchmark("ChannelObjectPool",
30+
// count => () => ChannelObjectPool.Create<object>((int)count * 2));
3131

32-
report.AddBenchmark("ConcurrentQueueObjectPool", // Note, that this one isn't far off from the following in peformance, but definitely is faster than LinkedListObjectPool and the rest.
32+
report.AddBenchmark("ConcurrentQueueObjectPool", // Note, that this one isn't far off from the following in peformance, but definitely is faster than LinkedListObjectPool and the rest.
3333
count => () => ConcurrentQueueObjectPool.Create<object>((int)count * 2));
3434

35-
report.AddBenchmark("ConcurrentStackObjectPool", // Note, that this one isn't far off from the following in peformance, but definitely is faster than LinkedListObjectPool and the rest.
36-
count => () => ConcurrentStackObjectPool.Create<object>((int)count * 2));
35+
report.AddBenchmark("ConcurrentStackObjectPool", // Note, that this one isn't far off from the following in peformance, but definitely is faster than LinkedListObjectPool and the rest.
36+
count => () => ConcurrentStackObjectPool.Create<object>((int)count * 2));
3737

38-
report.AddBenchmark("OptimisticArrayObjectPool",
38+
report.AddBenchmark("OptimisticArrayObjectPool",
3939
count => () => OptimisticArrayObjectPool.Create<object>((int)count * 2));
4040

41-
// Is ineveitably slower than the above but should be enabled for testing code changes.
42-
//report.AddBenchmark("InterlockedArrayObjectPool",
43-
// count => () => InterlockedArrayObjectPool.Create<object>((int)count * 2));
41+
// Is ineveitably slower than the above but should be enabled for testing code changes.
42+
//report.AddBenchmark("InterlockedArrayObjectPool",
43+
// count => () => InterlockedArrayObjectPool.Create<object>((int)count * 2));
4444

45-
report.Pretest(200, 200); // Run once through first to scramble/warm-up initial conditions.
45+
report.Pretest(200, 200); // Run once through first to scramble/warm-up initial conditions.
4646

4747
Console.SetCursorPosition(0, Console.CursorTop);
4848

49-
const int loopMultiple = 2;
49+
const int loopMultiple = 2;
5050
report.Test(4, 8 * loopMultiple);
5151
report.Test(10, 8 * loopMultiple);
5252
report.Test(50, 12 * loopMultiple);
@@ -68,4 +68,4 @@ static void Main(string[] args)
6868
Console.ReadKey();
6969
}
7070

71-
}
71+
}

source/Array/InterlockedArrayObjectPool.cs

Lines changed: 96 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -5,100 +5,100 @@
55

66
namespace Open.Disposable
77
{
8-
/// <summary>
9-
/// An extremely fast ObjectPool when the capacity is in the low 100s.
10-
/// </summary>
11-
/// <typeparam name="T"></typeparam>
12-
public class InterlockedArrayObjectPool<T> : ObjectPoolBase<T>
13-
where T : class
14-
{
15-
16-
public InterlockedArrayObjectPool(Func<T> factory, Action<T> recycler, int capacity = DEFAULT_CAPACITY)
17-
: base(factory, recycler, capacity)
18-
{
19-
Pool = new ReferenceContainer<T>[capacity - 1];
20-
}
21-
22-
public InterlockedArrayObjectPool(Func<T> factory, int capacity = DEFAULT_CAPACITY)
23-
: this(factory, null, capacity)
24-
{ }
25-
26-
protected ReferenceContainer<T>[] Pool;
27-
28-
// Sets a limit on what has been stored yet to prevent over searching the array unnecessarily..
29-
protected int MaxStored = 0;
30-
protected const int MaxStoredIncrement = 5; // Instead of every one.
31-
32-
protected override bool Receive(T item)
33-
{
34-
var elements = Pool;
35-
var len = elements?.Length ?? 0;
36-
37-
for (int i = 0; i < len; i++)
38-
{
39-
if (elements[i].TrySave(item))
40-
{
41-
var m = MaxStored;
42-
if (i >= m) Interlocked.CompareExchange(ref MaxStored, m + MaxStoredIncrement, m);
43-
44-
return true;
45-
}
46-
}
47-
48-
return false;
49-
}
50-
51-
protected override T TryRelease()
52-
{
53-
// We missed getting the first item or it wasn't there.
54-
var elements = Pool;
55-
if (elements == null) return null;
56-
57-
var len = elements.Length;
58-
for (int i = 0; i < MaxStored && i < len; i++)
59-
{
60-
var item = elements[i].TryRetrieve();
61-
if (item != null) return item;
62-
}
63-
64-
return null;
65-
}
66-
67-
protected override void OnDispose(bool calledExplicitly)
68-
{
69-
Pool = null;
70-
MaxStored = 0;
71-
}
72-
73-
}
74-
75-
public static class InterlockedArrayObjectPool
76-
{
77-
public static InterlockedArrayObjectPool<T> Create<T>(Func<T> factory, int capacity = Constants.DEFAULT_CAPACITY)
78-
where T : class
79-
{
80-
return new InterlockedArrayObjectPool<T>(factory, capacity);
81-
}
82-
83-
public static InterlockedArrayObjectPool<T> Create<T>(int capacity = Constants.DEFAULT_CAPACITY)
84-
where T : class, new()
85-
{
86-
return Create(() => new T(), capacity);
87-
}
88-
89-
public static InterlockedArrayObjectPool<T> Create<T>(Func<T> factory, bool autoRecycle, int capacity = Constants.DEFAULT_CAPACITY)
90-
where T : class, IRecyclable
91-
{
92-
Action<T> recycler = null;
93-
if (autoRecycle) recycler = Recycler.Recycle;
94-
return new InterlockedArrayObjectPool<T>(factory, recycler, capacity);
95-
}
96-
97-
public static InterlockedArrayObjectPool<T> Create<T>(bool autoRecycle, int capacity = Constants.DEFAULT_CAPACITY)
98-
where T : class, IRecyclable, new()
99-
{
100-
return Create(() => new T(), autoRecycle, capacity);
101-
}
102-
103-
}
8+
/// <summary>
9+
/// An extremely fast ObjectPool when the capacity is in the low 100s.
10+
/// </summary>
11+
/// <typeparam name="T"></typeparam>
12+
public class InterlockedArrayObjectPool<T> : ObjectPoolBase<T>
13+
where T : class
14+
{
15+
16+
public InterlockedArrayObjectPool(Func<T> factory, Action<T> recycler, int capacity = DEFAULT_CAPACITY)
17+
: base(factory, recycler, capacity)
18+
{
19+
Pool = new ReferenceContainer<T>[capacity - 1];
20+
}
21+
22+
public InterlockedArrayObjectPool(Func<T> factory, int capacity = DEFAULT_CAPACITY)
23+
: this(factory, null, capacity)
24+
{ }
25+
26+
protected ReferenceContainer<T>[] Pool;
27+
28+
// Sets a limit on what has been stored yet to prevent over searching the array unnecessarily..
29+
protected int MaxStored = 0;
30+
protected const int MaxStoredIncrement = 5; // Instead of every one.
31+
32+
protected override bool Receive(T item)
33+
{
34+
var elements = Pool;
35+
var len = elements?.Length ?? 0;
36+
37+
for (int i = 0; i < len; i++)
38+
{
39+
if (elements[i].TrySave(item))
40+
{
41+
var m = MaxStored;
42+
if (i >= m) Interlocked.CompareExchange(ref MaxStored, m + MaxStoredIncrement, m);
43+
44+
return true;
45+
}
46+
}
47+
48+
return false;
49+
}
50+
51+
protected override T TryRelease()
52+
{
53+
// We missed getting the first item or it wasn't there.
54+
var elements = Pool;
55+
if (elements == null) return null;
56+
57+
var len = elements.Length;
58+
for (int i = 0; i < MaxStored && i < len; i++)
59+
{
60+
var item = elements[i].TryRetrieve();
61+
if (item != null) return item;
62+
}
63+
64+
return null;
65+
}
66+
67+
protected override void OnDispose(bool calledExplicitly)
68+
{
69+
Pool = null;
70+
MaxStored = 0;
71+
}
72+
73+
}
74+
75+
public static class InterlockedArrayObjectPool
76+
{
77+
public static InterlockedArrayObjectPool<T> Create<T>(Func<T> factory, int capacity = Constants.DEFAULT_CAPACITY)
78+
where T : class
79+
{
80+
return new InterlockedArrayObjectPool<T>(factory, capacity);
81+
}
82+
83+
public static InterlockedArrayObjectPool<T> Create<T>(int capacity = Constants.DEFAULT_CAPACITY)
84+
where T : class, new()
85+
{
86+
return Create(() => new T(), capacity);
87+
}
88+
89+
public static InterlockedArrayObjectPool<T> Create<T>(Func<T> factory, bool autoRecycle, int capacity = Constants.DEFAULT_CAPACITY)
90+
where T : class, IRecyclable
91+
{
92+
Action<T> recycler = null;
93+
if (autoRecycle) recycler = Recycler.Recycle;
94+
return new InterlockedArrayObjectPool<T>(factory, recycler, capacity);
95+
}
96+
97+
public static InterlockedArrayObjectPool<T> Create<T>(bool autoRecycle, int capacity = Constants.DEFAULT_CAPACITY)
98+
where T : class, IRecyclable, new()
99+
{
100+
return Create(() => new T(), autoRecycle, capacity);
101+
}
102+
103+
}
104104
}

0 commit comments

Comments
 (0)