Hi, today I was trying to create a collection that Garbage Collector will fallen in love ;).
namespace ConstantMemoryQueueSandbox { using System; using System.Collections.Generic; using System.Diagnostics; using System.Runtime.CompilerServices; using System.Threading.Tasks; public class ConstantMemoryQueue<T> { readonly T[] data; readonly int capacity; public ConstantMemoryQueue(int capacity) { this.data = new T[capacity]; this.capacity = capacity; } int putId = -1; [MethodImpl(MethodImplOptions.Synchronized)] int GetNextPutID() { putId = capacity < putId + 1 ? ++putId : 0; return putId; } public void Enqueue(T item) { var putId = GetNextPutID(); data[putId] = item; } int getId = -1; [MethodImpl(MethodImplOptions.Synchronized)] int GetNextGetID() { getId = capacity < getId + 1 ? ++getId : 0; return getId; } public T Dequeue() { var getId = GetNextGetID(); return data[getId]; } public int Count { get { return putId > getId ? putId - getId : capacity - putId + getId; } } public bool IsEmpty { get { return putId == getId; } } // TODO // public bool isFull { // get { return false; } // } } public class ConstantMemoryBasedQueue<T> { readonly Queue<T> data; readonly int length; public ConstantMemoryBasedQueue(int capacity) { data = new Queue<T>(capacity); length = capacity; } [MethodImpl(MethodImplOptions.Synchronized)] public void Enqueue(T item) { data.Enqueue(item); } [MethodImpl(MethodImplOptions.Synchronized)] public T Dequeue() { return data.Dequeue(); } } class TestProgram { static void Main(string[] args) { var queueT = new ConstantMemoryQueue<string>(3); queueT.Enqueue("A"); queueT.Enqueue("B"); var a = queueT.Dequeue(); queueT.Enqueue("C"); var b = queueT.Dequeue(); var c = queueT.Dequeue(); if (a != "A" && b != "B" && c != "C") { Console.WriteLine("FAIL!"); return; } var queue = new ConstantMemoryQueue<int>(1000000); Console.WriteLine("FAST"); for (var t = 0; t < 5; ++t) { var meter = Stopwatch.StartNew(); Parallel.For(0, 1000000, i => queue.Enqueue(i)); meter.Stop(); Console.WriteLine("1 mln enqueue took {0} ms.", meter.ElapsedMilliseconds); meter.Reset(); meter.Start(); string r; Parallel.For(0, 1000000, i => queue.Dequeue()); meter.Stop(); Console.WriteLine("1 mln dequeue took {0} ms.", meter.ElapsedMilliseconds); } var queue2 = new ConstantMemoryBasedQueue<int>(1000000); Console.WriteLine("DEFAULT"); for (var t = 0; t < 5; ++t) { var meter = Stopwatch.StartNew(); Parallel.For(0, 1000000, i => queue2.Enqueue(i)); meter.Stop(); Console.WriteLine("1 mln enqueue took {0} ms.", meter.ElapsedMilliseconds); meter.Reset(); meter.Start(); string r; Parallel.For(0, 1000000, i => queue2.Dequeue()); meter.Stop(); Console.WriteLine("1 mln dequeue took {0} ms.", meter.ElapsedMilliseconds); } Console.ReadKey(true); } } }
P ;).