LDARG_0

.........

C#的Dictionary初步讨论与更佳的使用方法

事实:不论是ArrayList,Hashtable,List<T>等几种集合,都离不开数组的实现,往简单方面理解,不妨认为这是一种"高级"的数组

首先说说List:

List<T>用起来十分方便,然而其实际上是对数组的一个包装,其要点为:List实例创建时会初始化一个数组与一个包含当前列表元素数量的标记,每当新的元素加入时标记增加1,如果数组长度不够,会重新初始化一个新的长度为原有数组2倍的新数组,再将原有数组的元素复制到新数组,然后用新的数组替代原有的数组.

接着说Dictionary,Dictionary对实际数据的维护与List的原理是类似的,不过他要同时维护两个数组,第一个数组为Key的Hash值,按照大小进行顺序排列,第二个数组为Key/Value对的数组.为了根据一个Key检索一个值,Dictionary需要首先计算Key的Hash值,根据这个Hash值计算在第二个数组中的可能位置,然后进行比较直到找到对应的值为止.

 

由此可以看出,Dictionary对数组的易用性优势是显而易见的,然而性能缺陷也是比较明显的,因此在进行编码时,如果二者都可以经由某种设计实现所需功能时,用数组无疑是最佳选择.

 

下面的代码显示了遍历一个数组与一个字典所带来的性能差异

    class Program
    {
        private enum Num
        {
            one = 1,
            two,
            three,
            four,
            five,
            six,
            seven,
            eight
        }
        static void Main(string[] args)
        {
            int[] array = new int[]{1, 2, 3, 4, 5, 6, 7, 8};
            Dictionary<Num, int> dict = new Dictionary<Num,int>()
            {
                {Num.one, 1},
                {Num.two, 2},
                {Num.three, 3},
                {Num.four, 4},
                {Num.five, 5},
                {Num.six, 6},
                {Num.seven, 7},
                {Num.eight, 8}
            };

            int max = 10000000;

            int n;

            Stopwatch sw = new Stopwatch();
            sw.Start();
            for (int i = 0; i < max; i++)
            {
                n = array[0] + array[1] + array[2] + array[3] + array[4] + array[5] + array[6] + array[7];
            }
            sw.Stop();
            Console.WriteLine(sw.Elapsed);
            sw.Restart();
            for (int i = 0; i < max; i++)
            {
                n = dict[Num.one] + dict[Num.two] + dict[Num.three] + dict[Num.four] + dict[Num.five] + dict[Num.six] + dict[Num.seven] + dict[Num.eight];
            }
            sw.Stop();
            Console.WriteLine(sw.Elapsed);

            sw.Restart();
            for (int i = 0; i < max; i++)
            {
                n = array[(int)Num.one - 1] + array[(int)Num.two - 1] + array[(int)Num.three - 1] + array[(int)Num.four - 1] + array[(int)Num.five - 1] + array[(int)Num.six - 1] + array[(int)Num.seven - 1] + array[(int)Num.eight - 1];
            }
            sw.Stop();
            Console.WriteLine(sw.Elapsed);

            Console.ReadLine();
        }
    }

 

  

输出:

00:00:00.1069296
00:00:01.5431100
00:00:00.1066442

------------------------------------------------

问题:使用数组存储数据当然性能较好,但是没有Key信息,索引也不好理解,也不易于扩展,怎么办

理解的问题可以通过定义常量解决

 

本文举例介绍一种某些情形下可以结合Enum解决的方案,在Key选项有限的情形下这种方式既照顾了性能,又易于阅读与扩展.

代码1:Enum定义

View Code
/// <summary>
    /// 物品类型
    /// </summary>
    public enum ItemType
    {
        /// <summary>
        /// 未知
        /// </summary>
        None = 0,
        /// <summary>
        /// 头盔
        /// </summary>
        Helmet = 1,
        /// <summary>
        /// 项链
        /// </summary>
        Necklace = 2,
        /// <summary>
        /// 护肩
        /// </summary>
        Shoulder = 3,
        /// <summary>
        /// 盔甲
        /// </summary>
        Amor = 4,
        /// <summary>
        /// 手套
        /// </summary>
        Gloves = 5,
        /// <summary>
        /// 腰带
        /// </summary>
        Belt = 6,
        /// <summary>
        /// 戒指
        /// </summary>
        Ring = 7,
        /// <summary>
        /// 裤子
        /// </summary>
        Trousers = 8,
        /// <summary>
        /// 靴子
        /// </summary>
        Boots = 9,
        /// <summary>
        /// 单手剑
        /// </summary>
        OneHandSword = 10,
        /// <summary>
        /// 双手剑
        /// </summary>
        TwoHandSword = 11,
        /// <summary>
        /// 单手杖
        /// </summary>
        OneHandStaff = 12,
        /// <summary>
        /// 双手杖
        /// </summary>
        TwoHandStaff = 13,
        /// <summary>
        /// 单手斧
        /// </summary>
        OneHandAxe = 14,
        /// <summary>
        /// 双手斧
        /// </summary>
        TwoHandAxe = 15,
        /// <summary>
        ////// </summary>
        Bow = 16,
        /// <summary>
        /// 弩枪
        /// </summary>
        OneHandCrossBow = 17,
        /// <summary>
        /// 双手弩
        /// </summary>
        TwoHandCrossBow = 18,
        /// <summary>
        /// 标枪
        /// </summary>
        Javelin = 19,
        /// <summary>
        /// 长矛
        /// </summary>
        Spear = 20,
        /// <summary>
        /// 匕首
        /// </summary>
        Dagger = 21,
        /// <summary>
        /// 单手锤
        /// </summary>
        OneHandHammer = 22,
        /// <summary>
        /// 双手锤
        /// </summary>
        TwoHandHammer = 23,
        /// <summary>
        /// 盾牌
        /// </summary>
        Shield = 24,
        /// <summary>
        /// 魔法书
        /// </summary>
        MagicBook = 25,
        /// <summary>
        /// 魔法球
        /// </summary>
        MagicBall = 26,
        /// <summary>
        /// 箭袋
        /// </summary>
        Quiver = 27
    }

 

代码2:数据的存储

            WorkShops = new IItemWorkshop[(Enum.GetValues(typeof(ItemType)) as int[]).Max() + 1];
            WorkShops[(int)ItemType.Helmet] = new DefenceItemWorkshop<Helmet>();
            WorkShops[(int)ItemType.Necklace] = new ItemWorkshop<Necklace>();
            WorkShops[(int)ItemType.Shoulder] = new DefenceItemWorkshop<Shoulder>();
            WorkShops[(int)ItemType.Amor] = new DefenceItemWorkshop<Amor>();
            WorkShops[(int)ItemType.Gloves] = new DefenceItemWorkshop<Gloves>();
            WorkShops[(int)ItemType.Belt] = new DefenceItemWorkshop<Belt>();
            WorkShops[(int)ItemType.Ring] = new ItemWorkshop<Ring>();
            WorkShops[(int)ItemType.Trousers] = new DefenceItemWorkshop<Trousers>();
            WorkShops[(int)ItemType.Boots] = new DefenceItemWorkshop<Boots>();
            WorkShops[(int)ItemType.OneHandSword] = new WeaponItemWorkshop<OneHandSword>();
            WorkShops[(int)ItemType.TwoHandSword] = new WeaponItemWorkshop<TwoHandSword>();
            WorkShops[(int)ItemType.OneHandStaff] = new WeaponItemWorkshop<OneHandStaff>();
            WorkShops[(int)ItemType.TwoHandStaff] = new WeaponItemWorkshop<TwoHandStaff>();
            WorkShops[(int)ItemType.OneHandAxe] = new WeaponItemWorkshop<OneHandAxe>();
            WorkShops[(int)ItemType.TwoHandAxe] = new WeaponItemWorkshop<TwoHandAxe>();
            WorkShops[(int)ItemType.Bow] = new ItemWorkshop<Bow>();
            WorkShops[(int)ItemType.OneHandCrossBow] = new WeaponItemWorkshop<OneHandCrossBow>();
            WorkShops[(int)ItemType.TwoHandCrossBow] = new WeaponItemWorkshop<TwoHandCrossBow>();
            WorkShops[(int)ItemType.Javelin] = new WeaponItemWorkshop<Javelin>();
            WorkShops[(int)ItemType.Spear] = new WeaponItemWorkshop<Spear>();
            WorkShops[(int)ItemType.Dagger] = new WeaponItemWorkshop<Dagger>();
            WorkShops[(int)ItemType.OneHandHammer] = new WeaponItemWorkshop<OneHandHammer>();
            WorkShops[(int)ItemType.TwoHandHammer] = new WeaponItemWorkshop<TwoHandHammer>();
            WorkShops[(int)ItemType.Shield] = new ShieldItemWorkshop();
            WorkShops[(int)ItemType.MagicBook] = new ItemWorkshop<MagicBook>();
            WorkShops[(int)ItemType.MagicBall] = new ItemWorkshop<MagicBall>();
            WorkShops[(int)ItemType.Quiver] = new ItemWorkshop<Quiver>();

posted on 2012-08-17 01:55  sumok  阅读(530)  评论(0编辑  收藏  举报

导航