Skip to content

Instantly share code, notes, and snippets.

View ocoanet's full-sized avatar

Olivier Coanet ocoanet

View GitHub Profile
@ocoanet
ocoanet / Sequencer V1
Last active August 29, 2015 14:01
Task based sequencer
using System;
using System.Threading.Tasks;
namespace Seq
{
public class Sequencer
{
private readonly object _lock = new object();
private Task _task = Task.FromResult(0);
@ocoanet
ocoanet / Sequencer V2
Last active August 29, 2015 14:01
Task based sequencer
using System;
using System.Threading;
using System.Threading.Tasks;
using log4net;
namespace Seq
{
// note: I do not usually comment my code that much :)
public class Sequencer
using System.Runtime.InteropServices;
using System.Threading;
namespace Foo
{
/// <summary>
/// Naive SPMC stack.
/// </summary>
public class NaiveStack
{
using System.Runtime.InteropServices;
using System.Threading;
namespace Foo
{
/// <summary>
/// Naive SPMC queue.
/// </summary>
public class NaiveQueue
{
public T this[long sequence]
{
get
{
var index = _bufferPad + (int)(sequence & _indexMask);
return (T)_entries[index];
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static T Read<T>(object array, int index)
{
IL.DeclareLocals(false, new LocalVar(typeof(byte).MakeByRefType()));
IL.Emit(OpCodes.Ldarg_0); // load the object
IL.Emit(OpCodes.Stloc_0); // convert the object pointer to a byref
IL.Emit(OpCodes.Ldloc_0); // load the object pointer as a byref
IL.Emit(OpCodes.Ldarg_1); // load the index
IL.Emit(OpCodes.Sizeof, typeof(object)); // get the size of the object pointer
Method | Mean | Error | StdDev |
------------------- |----------:|----------:|----------:|
Publish | 0.8713 ns | 0.0116 ns | 0.0108 ns |
PublishPinning | 2.0890 ns | 0.0128 ns | 0.0119 ns |
IsAvailable | 0.7125 ns | 0.0029 ns | 0.0024 ns |
IsAvailablePinning | 2.0291 ns | 0.0136 ns | 0.0120 ns |
Method | Mean | Error | StdDev | Scaled | ScaledSD |
------------------ |----------:|----------:|----------:|-------:|---------:|
IndexerIL | 0.5106 ns | 0.0017 ns | 0.0015 ns | 1.00 | 0.00 |
IndexerUnsafe | 2.4546 ns | 0.0147 ns | 0.0131 ns | 4.81 | 0.03 |
IndexerArray | 1.5966 ns | 0.0048 ns | 0.0045 ns | 3.13 | 0.01 |
# Array + AggressiveInlining (OneToOneSequencedBatchThroughputTest)
Run: Ops: 276 157 615 - Duration: 3 621 (ms)
Run: Ops: 276 788 198 - Duration: 3 613 (ms)
Run: Ops: 277 759 098 - Duration: 3 600 (ms)
Run: Ops: 276 879 343 - Duration: 3 612 (ms)
Run: Ops: 276 884 548 - Duration: 3 612 (ms)
# IL + AggressiveInlining (OneToOneSequencedBatchThroughputTest)
Run: Ops: 373 840 259 - Duration: 2 675 (ms)
Run: Ops: 378 799 243 - Duration: 2 640 (ms)
# Array (OneToOneSequencedBatchThroughputTest)
Run: Ops: 112 706 424 - Duration: 8 873 (ms)
Run: Ops: 111 356 333 - Duration: 8 980 (ms)
Run: Ops: 110 476 411 - Duration: 9 052 (ms)
Run: Ops: 111 678 223 - Duration: 8 954 (ms)
Run: Ops: 111 526 217 - Duration: 8 967 (ms)
# Unsafe (OneToOneSequencedBatchThroughputTest)
Run: Ops: 206 831 897 - Duration: 4 835 (ms)
Run: Ops: 208 979 660 - Duration: 4 785 (ms)