Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • Home
  • SEARCH
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8559985
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 11, 20262026-06-11T16:10:35+00:00 2026-06-11T16:10:35+00:00

We have an enormous program that is generating too much garbage. This is hurting

  • 0

We have an enormous program that is generating too much garbage. This is hurting performance, generating thousands of soft page faults every second, reducing latency, hurting throughput, etc.

One of the prime culprits is System.Collections.Generic.Dictionary, so we would like to replace it with a version that allows us to pre-allocate say 10,000 entries, then reuse these entries on the fly.

Are there any existing implemenations of Dictionary that allow pre-allocation of entries, and do not generate garbage at runtime?

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-11T16:10:36+00:00Added an answer on June 11, 2026 at 4:10 pm

    We decided not to use the garbage free dictionary in the end, as it didn’t impact overall GC that much.

    For the record, here is an implementation of a garbage free dictionary. Its memory hungry, but it works well.

    To use, instantiate a new dictionary, with enough slots for the potential integer keys. For example, if the primary integer key could range between 0 and 50,000, then you will need to pass 50,000 in when you instantiate it:

    MyIntegerKeyDictionary = new MyIntegerKeyDictionary<int, MyClass>(50000);
    

    If the key could range from 200,000 to 250,000, instantiate it with 50,000 potential keys, and it will automatically “rebase” the key (based on the first key it sees) so it can range from 200,000 to 250,000.

    using System;
    using System.Collections.Concurrent;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading;
    using MyLogType;
    
    namespace MyHelper
    {
    /// <summary>
    /// NOTE: Non thread safe, only run this individually.
    /// </summary>
    /// <typeparam name="T">Type of item we are adding to the dictionary.</typeparam>
    public class MyIntegerKeyDictionary<T> where T : class
    {
        /// <summary>
        /// Array in which we store the entries.
        /// </summary>
        volatile private T[] ArrayToUse;
    
        /// <summary>
        /// Allows us to check the maximum size, just in case.
        /// </summary>
        private readonly int SizeInternal;
    
        /// <summary>
        /// Keeps track of the current number of items in the dictionary.
        /// </summary>
        public int Count = 0;
    
        /// <summary>
        /// Base number. For numbers that start with a huge base, this allows the index to work without allocating megabytes of memory.
        /// </summary>
        private int BaseNumberToAdd { get; set; }
    
        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="Size">Size of the dictionary.</param>
        public MyIntegerKeyDictionary(int Size)
        {
            // Create the array to hold n number of items.
            ArrayToUse = new T[Size];
    
            // We must touch all of these entries, to force page faults now (rather than later).
            for (int i = 0; i < ArrayToUse.Length; i++)
            {
                ArrayToUse[i] = null;
            }
            BaseNumberToAdd = int.MinValue;
    
            this.SizeInternal = Size;
        }
    
        /// <summary>
        /// Add an item.
        /// </summary>
        /// <param name="Key">Key.</param>
        /// <param name="Value">Value.</param>
        /// <returns>True if the item was added, false if not.</returns>
        public bool TryAdd(int Key, T Value)
        {
            if (BaseNumberToAdd == int.MinValue)
            {
                BaseNumberToAdd = Key;
                //Console.Write(string.Format("{0}Message W20120907-3751. TryAdd. Adding first item {1}.\n",
                //MyLog.NPrefix(), Key));
            }
            Key = Key - BaseNumberToAdd;
    
            if (Key < 0)
            {
                Console.Write(string.Format("{0}Warning W20120907-3750. TryAdd. Attempted to add a key with index {1} which is < 0.\n",
                    MyLog.NPrefix(), Key));
                return false;
            }
    
            if (Key >= this.SizeInternal)
            {
                Console.Write(string.Format("{0}Warning W20120907-3756. TryAdd. Attempted to add a key with index {1} which is > max {2}\n",
                    MyLog.NPrefix(), Key, this.SizeInternal));
                return false;
            }
    
            if (ArrayToUse[Key] == null)
            {
                Interlocked.Increment(ref Count);
            }
    
            ArrayToUse[Key] = Value;
            return true;
        }
    
        /// <summary>
        /// Remove an item from the dictionary.
        /// </summary>
        /// <param name="Key">Key that we want to remove.</param>
        /// <returns>True if the item could be removed, false if not.</returns>
        public bool TryRemove(int Key)
        {
            if (BaseNumberToAdd == int.MinValue)
            {
                Console.Write(string.Format("{0}Warning W20120907-8756. TryRemove. Attempted to remove an item without any items in the dictionary yet {1}.\n",
                    MyLog.NPrefix(), Key));
                return false;
            }
            Key = Key - BaseNumberToAdd;
    
    
            if (Key < 0)
            {
                Console.Write(string.Format("{0}Warning W20120907-9756. TryRemove. Attempted to remove a key with index {1} which is < 0.\n",
                    MyLog.NPrefix(), Key));
                return false;
            }
    
            if (Key >= this.SizeInternal)
            {
                Console.Write(string.Format("{0}Warning W20120907-6756. TryRemove. Attempted to remove a key with index {1} which is > max {2}\n",
                    MyLog.NPrefix(), Key, this.SizeInternal));
                return false;
            }
    
            if (ArrayToUse[Key] != null)
            {
                Interlocked.Decrement(ref Count);
            }
    
            ArrayToUse[Key] = null;
    
            return true;
        }
    
    
        /// <summary>
        /// Indexer.
        /// </summary>
        /// <param name="key">Key.</param>
        /// <returns>Value.</returns>
        public T this[int key]
        {
            get
            {
                T valueToReturn;
                TryGetValue(key, out valueToReturn);
                return valueToReturn;
            }
        }
    
        /// <summary>
        /// Attempt to get the value.
        /// </summary>
        /// <param name="Key">Key.</param>
        /// <param name="Value">Value.</param>
        /// <returns>True if the value exists, false if not.</returns>
        public bool TryGetValue(int Key, out T Value)
        {
            Value = null;
            if (BaseNumberToAdd == int.MinValue)
            {
                Console.Write(string.Format("{0}Warning W20120907-8756. TryGetValue. Attempted to retrieve an item without any items in the dictionary yet {1}.\n",
                    MyLog.NPrefix(), Key));
                return false;
            }
            Key = Key - BaseNumberToAdd;
            if (ArrayToUse[Key] == null)
            {
    
                return false;
            }
    
            Value = ArrayToUse[Key];
            return true;
        }
    
        /// <summary>
        /// Checks to see if the key exists.
        /// </summary>
        /// <param name="Key">Key index.</param>
        /// <returns>True if the item exists, false if not.</returns>
        public bool ContainsKey(int Key)
        {
            if (Key == 0)
            {
                Console.Write(string.Format("{0}Warning W20120907-1914. ContainsKey. Have not rebased yet. Ignoring query for ContainsKey(0).\n",
                    MyLog.NPrefix()));
                return false;
            }
    
            if (BaseNumberToAdd == int.MinValue)
            {
                Console.Write(string.Format("{0}Warning W20120907-8756. ContainsKey. Attempted to check if Key {1} exists, however BaseNumber is not set yet.\n",
                    "", Key));
                return false;
            }
            Key = Key - BaseNumberToAdd;
    
            if (Key < 0)
            {
                Console.Write(string.Format("{0}Warning W20120907-8756. ContainsKey. Key = {1} which is < 0.\n",
                    "", Key));
                return false;
            }
    
            if (Key >= this.SizeInternal)
            {
                MyLogAsync.LogWarning(string.Format("{0}Warning W20120907-5756. ContainsKey. Key({1}) >= this.SizeInternal ({2}).\n",
                    MyLog.NPrefix(), Key, this.SizeInternal));
                return false;
            }
    
            if (ArrayToUse[Key] == null)
            {
                return false;
            }
            return true;
        }
        /*
        private bool CheckKeyBounds(int Key, string description)
        {
            if (Key < 0)
            {
                MyLogAsync.LogWarning(string.Format("{0}Warning W20120907-8756. {1}. Attempted to add a key with index {2} which is < 0.\n",
                    MyLog.NPrefix(), description, Key));
            }
    
            if (Key >= this.SizeInternal)
            {
                MyLogAsync.LogWarning(string.Format("{0}Warning W20120907-5756. {1}. Attempted to add a key with index {2} which is > max {3}\n",
                    MyLog.NPrefix(), description, Key, this.SizeInternal));
                return false;
            }
        }
        */
    }
    }
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have this enormous database : # # Dropping tables # DROP TABLE IF
So I have a page with an enormous table in a CRUD interface of
I have a function that is doing memcpy, but it's taking up an enormous
I hope this isn't too vague, but I'm stuck on a problem that has
i have this broadcastreceiver that executes some code from time to time and triggers
I built a quick program that needed to loop through an enormous log file
I have an enormous file of HTML that I'd like to convert to one
We have an App for iOS that renders an enormous amount of text: http://itunes.apple.com/br/app/biblia-sagrada/id370178518?mt=8
On Mac OSX 5.8 I have a Java program that runs at 100% CPU
I have a performance counters reporter class that holds in multiple members different lists.

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.