Constant Memory Queues of T

imageHi, 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 ;).

Leave a Reply

Your email address will not be published. Required fields are marked *

*

This site uses Akismet to reduce spam. Learn how your comment data is processed.