• 2019-11-29-C#-字典-Dictionary-的-TryGetValue-与先判断-ContainsKey-然后-Get-的性能对比


    title author date CreateTime categories
    C# 字典 Dictionary 的 TryGetValue 与先判断 ContainsKey 然后 Get 的性能对比
    lindexi
    2019-11-29 10:13:19 +0800
    2018-09-08 15:33:40 +0800
    C#

    本文使用 benchmarkdotnet 测试字典的性能,在使用字典获取一个可能存在的值的时候可以使用两个不同的写法,于是本文分析两个写法的性能。

    判断值存在,如果值存在就获取值,可以使用下面两个不同的方法

    一个方法是使用 TryGetValue 请看下面代码

                if (Dictionary.TryGetValue(xx, out var foo))
                {
                }

    另一个方法是先判断是否存在然后再获取,请看下面代码

    if(Dictionary.ContainsKey(xx))
    {
    	var foo = Dictionary[xx];
    }

    于是本文就使用benchmarkdotnet 测试两个方法的性能

    下面是进行测试的数据,测试的代码放在本文的最后。这里的 TryGetExist 方法就是尝试获取一个值,这个值是存在的。而 ContainGetExist 是先判断值是否存在,如果存在就尝试获取这个值。

    BenchmarkDotNet=v0.10.14, OS=Windows 10.0.17134
    Intel Core i7-6700 CPU 3.40GHz (Skylake), 1 CPU, 8 logical and 4 physical cores
    Frequency=3328130 Hz, Resolution=300.4690 ns, Timer=TSC
      [Host]     : .NET Framework 4.7 (CLR 4.0.30319.42000), 64bit RyuJIT-v4.7.3132.0  [AttachedDebugger]
      DefaultJob : .NET Framework 4.7 (CLR 4.0.30319.42000), 64bit RyuJIT-v4.7.3132.0
    
    
    Method Mean Error StdDev Median
    TryGetExist 30.26 ns 0.6057 ns 0.5949 ns 30.11 ns
    ContainGetExist 46.36 ns 1.0883 ns 3.1919 ns 44.90 ns
    TryGetNoExist 20.23 ns 0.4661 ns 0.7658 ns 19.93 ns
    ContainGetNoExist 18.68 ns 0.2569 ns 0.2403 ns 18.66 ns

    同样对比 ConcurrentDictionary 线程安全的类的性能,也就是将会上面的 Foo 测试类的字典替换为 ConcurrentDictionary 其他代码都不修改,下面是测试的数据,可以看到使用 TryGetValue 的性能依然比较好

    BenchmarkDotNet=v0.10.14, OS=Windows 10.0.17134
    Intel Core i7-6700 CPU 3.40GHz (Skylake), 1 CPU, 8 logical and 4 physical cores
    Frequency=3328130 Hz, Resolution=300.4690 ns, Timer=TSC
      [Host]     : .NET Framework 4.7 (CLR 4.0.30319.42000), 64bit RyuJIT-v4.7.3132.0  [AttachedDebugger]
      DefaultJob : .NET Framework 4.7 (CLR 4.0.30319.42000), 64bit RyuJIT-v4.7.3132.0
    
    
    Method Mean Error StdDev Median
    TryGetExist 31.20 ns 0.4644 ns 0.3625 ns 31.17 ns
    ContainGetExist 66.80 ns 2.4692 ns 7.2806 ns 63.84 ns
    TryGetNoExist 20.07 ns 0.1254 ns 0.1112 ns 20.04 ns
    ContainGetNoExist 27.63 ns 0.4230 ns 0.3956 ns 27.65 ns

    所有代码

        public class Foo
        {
            /// <inheritdoc />
            public Foo()
            {
                var ran = new Random();
                bool set = false;
                for (int i = 0; i < 100000; i++)
                {
                    LazyDictionary[ran.Next().ToString() + "-" + i.ToString()] = ran.Next().ToString();
                    if (!set)
                    {
                        if (ran.Next() < i)
                        {
                            set = true;
                            LazyDictionary["lindexi"] = "逗比";
                        }
                    }
                }
            }
    
            [Benchmark]
            public void TryGetExist()
            {
                if (LazyDictionary.TryGetValue("lindexi", out var foo))
                {
                    _foo = foo;
                }
            }
    
            [Benchmark]
            public void ContainGetExist()
            {
                if (LazyDictionary.ContainsKey("lindexi"))
                {
                    _foo = LazyDictionary["lindexi"];
                }
            }
    
    
            [Benchmark]
            public void TryGetNoExist()
            {
                if (LazyDictionary.TryGetValue("lindexi123", out var foo))
                {
                    _foo = foo;
                }
            }
    
            [Benchmark]
            public void ContainGetNoExist()
            {
                if (LazyDictionary.ContainsKey("lindexi123"))
                {
                    _foo = LazyDictionary["lindexi123"];
                }
            }
    
            private object _foo;
    
            private Dictionary<string, object> LazyDictionary { get; } = new Dictionary<string, object>();
    
        }
    

    我的博客即将搬运同步至腾讯云+社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan?invite_code=19bm8i8js1ezb

  • 相关阅读:
    N、Z、Q、R 分别代表什么
    Android常用代码-监听网络状态
    完整的android use SSL发送邮件
    android 发送邮件相关文章
    Spring RMI的实现原理
    spring+quartz配置
    Quartz配置表达式
    singleton容器
    Spring学习-框架概览
    [Shader2D]漩涡效果
  • 原文地址:https://www.cnblogs.com/lindexi/p/12085395.html
Copyright © 2020-2023  润新知