C# 字典,键是字符串,值是计数器。近似算法和线程安全

标签 c# multithreading dictionary concurrency

class Program
    {
        static Dictionary<string, int> Dictionary = new Dictionary<string, int>();

        static void Main(string[] args)
        {
            Stopwatch stopwatch = new Stopwatch();
            stopwatch.Start();

            Thread[] threads = new Thread[500];

            for(int i = 0; i < threads.Length; i++)
            {
                threads[i] = new Thread(InsertAlphabet);
                threads[i].Start();
            }
            for (int i = 0; i < threads.Length; i++)
            {
                threads[i].Join();
            }

            Console.WriteLine(Dictionary.Count);

            Console.WriteLine(stopwatch.ElapsedMilliseconds);

            foreach (KeyValuePair<string,int> kvp in Dictionary)
            {
                Console.WriteLine(kvp.Key + " " + kvp.Value);
            }

            stopwatch.Stop();
            Console.ReadLine();

        }

        private static void InsertAlphabet()
        {
            string[] alphabetArray = { "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z" };
            foreach (var alphabet in alphabetArray)
            {
                Add(alphabet);
            }
        }

        public static void Add(string bar)
        {
            lock (Dictionary)
            {
                if (!Dictionary.ContainsKey(bar))
                {
                    Dictionary.Add(bar, 1);
                }
                else
                {
                    Dictionary[bar] += 1;
                }
            }
        }
    }

我创建了这个简单的控制台应用程序来确保插入字典的数据是准确的。

对于同时尝试插入的 500 个线程,我将字母表作为键插入并将计数作为值插入的时间约为 3 秒。

有没有一种方法可以通过涉及某种近似值来提高性能(数据不需要 100% 准确。允许的准确度为 95%)。

还有关于如何改进字典中计数增量的建议。

最佳答案

我相信您可以使用 AddOrUpdate 的 ConcurrentDictionary 重载安全地完成此操作这需要委托(delegate)来生成新值。

委托(delegate)接收当前值,如果有的话。您可以提供将增量值添加到现有值的委托(delegate)实现。如果尚不存在值,则提供给 AddOrUpdate 的参数将直接分配为该键的值。

由于使用此解决方案,ConcurrentDictionary 在内部锁定正在更新的键值,直到您的委托(delegate)返回并更新内部值,多线程性能应该比您当前锁定整个字典结构要好得多。

关于C# 字典,键是字符串,值是计数器。近似算法和线程安全,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31462988/

相关文章:

c# - 如何通过testfixture参数运行测试方法?

c# - 哪种方式更好?将媒体文件作为字节数组还是字符串保存到 MongoDB?

java - 如何迭代可以由另一个线程添加到的列表

java - LinkedHashMap顺序

python - 在列表字典中搜索值

c# - HttpClient 返回特殊字符但没有可读性

c# - SQLite:没有这样的表

java - 无法在 IntelliJ 中进入 Debug模式的方法?

java - 什么是 JaMP,我如何了解它?

作用于一串数字的python map函数