也谈枚举ToString()性能的改进

7 篇文章 0 订阅

也谈枚举ToString()性能的改进

昨天看到 “性能相差7千倍的ToString方法”这篇文章,对于作者这种良好的性能意识和探索精神很佩服,以前还真没注意到这点。

不过,用switch的做法,个人觉得虽然性能上去了,但是可维护性就下来了,以后该枚举要增加或删除一项,这段switch代码都要改一下,其实该问题的关键就是反射带来的性能损耗,在调用枚举的ToString()方法时,无非就是要得到一个字符串而已,我个人更倾向于用key-value这种经典的键值对来优化。

下面是示例代码:

 public static class TestClass
    {
        public static Dictionary<int, string> EnumLoginErrorNames = new Dictionary<int, string>();

        //静态私有构造器
        static TestClass()
        {
            AddEnumLoginErrorToDic(); //自动将枚举放入对应的字典中           
        }

        public enum EnumLoginError
        {
            用户名不存在,
            密码错误,
            用户被锁定,
            未知错误
        }

        private static void AddEnumLoginErrorToDic()
        {

            string[] _names = Enum.GetNames(typeof(EnumLoginError));
            int[] _values = Enum.GetValues(typeof(EnumLoginError)) as int[];

            for (int i = 0; i < _values.Length; i++)
            {
                EnumLoginErrorNames.Add(_values[i], _names[i]);
            }            
        }
    }

这样处理后的性能测试代码:(asp.net页中测试的,主要只是对比一下跟传统ToString方法的差异而已)

protected void Page_Load(object sender, EventArgs e)
        {
            Stopwatch sw = new Stopwatch();
            int _max = 1000000,i=0;

            string _temp = TestClass.EnumLoginErrorNames[(int)TestClass.EnumLoginError.用户被锁定];//先调用一次,以便预热

            //Dictionary方法 计时开始
            sw.Start();
            for (i = 0; i < _max; i++)
            {

                _temp = TestClass.EnumLoginErrorNames[(int)TestClass.EnumLoginError.用户被锁定]; 
            }
            sw.Stop();
            Debug.WriteLine("Dictionary方法耗时:" + sw.ElapsedMilliseconds);
            sw.Reset();

            //反射方法 计时开始
            sw.Start();
            for (i = 0; i < _max; i++)
            {
                _temp = TestClass.EnumLoginError.用户被锁定.ToString();
            }
            sw.Stop();

            Debug.WriteLine("反射方法 耗时:" + sw.ElapsedMilliseconds);


        }

在我的本本上跑出来的测试结果如下:

Dictionary方法耗时:28
反射方法 耗时:1384

效果还是比较明显的,相对于switch方法而言,没有将结果字符串硬编码在处理函数中,以后枚举中增加或删除某一项,也不影响调用代码,可维护性相对更好一些。但是也应该看到,这是一种空间换时间的做法,避开了反射,但是系统需要额外存储一个字典对象,占用的内存要比原来多一些。

最后:本文仅为技术探讨,没有哪个最好之说,具体如何使用,大家自己酌情考虑。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值