VB.net 2010 视频教程 VB.net 2010 视频教程 python基础视频教程
SQL Server 2008 视频教程 c#入门经典教程 Visual Basic从门到精通视频教程
当前位置:
首页 > c#编程 >
  • 如何写出高质量的代码之数组优化

如何写出高质量有代码,首先,要看我们的目的及高质量代码的标准,一直以来,都认为高质量的代码就是体积小、速度快;不错,这确实是高质量代码所应具备的特征,但这不是全部,除此之外,还要考虑到CPU时钟占用及内存等因素。这里先简单说一下对集合的使用,在C#中的集合主要是数组和其它一些集合类;对这些集合类的使用是很有讲究的。
第一点,元素可变的情况下不要使用数组
  在C#教程中,数组被创建后,长度是不能改变的。如需一个动态且可变长度的集合,就应该使用ArrayList或List<T>。而数组本身,尤其是一维数组,在遇到要求高效率的算法时,则会专门被优化以提升其效率。一维数组也称为向量,其性能是最佳的,在IL中使用了专门的指令来处理它们。
  从内存使用的角度来讲,数组具有以下特点:
  1、数组在创建时被分配了一段固定长度的内存。
  2、如果数组元素是值类型,则每个元素的长度等于相应的值类型的长度
  3、如果数组的元素是引用类型,则每个元素的长度为该引用类型的IntPtr.Size。
  4、数组的存储结构一旦被分配,就不能再变化。
  而ArryaList是这样的:
  1、ArrayList是链表结构,可以动态增减内存空间。
  2、如果ArrayList存储的是值类型,则会为每个元素增加12字节的空间,其中4字节用于对象引用,8字节是元素装箱时引入的对象头。
  而List<T>是ArrayList的泛型实现,它省去了拆箱和装箱带来的开销。
如果一定要动态改变数组的长度,一种方法是将数组转换为ArrayList或List<T>,如下面的代码所示:

            ///定义一个一维数组
            int[] iArr = { 0,1,3,4,6,7,9};
            ///将数组转换为ArrayList
            ArrayList arrayListInt = ArrayList.Adapter(iArr);
            arrayListInt.Add(11);
            ///将数组转换为List<T>
            List<int> listInt = iArr.ToList<int>();
            listInt.Add(11);

  还有一种方法是用数组的复制功能。数组继承自System.Array,抽象类System.Array提供了一些有用的实现方法,其中就包含了Copy方法,它负责将一个数组的内容复制到另外一个数组中。无论是哪种方法,改变数组长度就相当于重新创建了一个数组对象。
  为了让数组看上去本身就具有动态改变长度的功能,还可以创建一个名为ReSize的扩展方法。

    public static class ClassForExtensions
    {
        public static Array ReSize(this Array array,int newSize)
        {
            Type t = array.GetType().GetElementType();
            Array newArray = Array.CreateInstance(t, newSize);
            Array.Copy(array, 0, newArray, 0, Math.Min(array.Length, newSize));
            return newArray;
        }
    }

调用方式如下:
        static void Main(string[] args)
        {
            int[] iArr = { 0,1,3,4,6,7,9};
            iArr = (int[])ClassForExtensions.ReSize(iArr, 20);
            Console.ReadLine();
        }
下面我们来对比一下性能,先来看代码:

    class Program
    {
        static void Main(string[] args)
        {
            ResizeArray();
            ResizeList();
            Console.ReadLine();
        }
 
        public static void ResizeArray()
        {
            int[] iArr = {0,1,3,4,6,8 };
            Stopwatch watch = new Stopwatch();
            watch.Start();///用于测量时间间隔
            iArr = (int[])iArr.ReSize(10);
            watch.Stop();///
            Console.WriteLine("ResizeArray:{0}", watch.Elapsed);
        }
 
        public static void ResizeList()
        {
            List<int> iArr = new List<int>(new int[] { 0, 1, 3, 4, 6, 8, 9 });
            Stopwatch watch = new Stopwatch();
            watch.Start();
            iArr.Add(0);
            iArr.Add(0);
            iArr.Add(0);
            watch.Stop();
            Console.WriteLine("ResizeList:{0}", watch.Elapsed);
        }
    }

Main函数中主要是调用,自己定义的两个方法,第一个是重新设置数组的长度,第二个是设置List<T>的长度,通过运行时间进行测量:

严格意义上讲,List<T>不存在改变长度的说法,此处主要是来进行对比一下,对List<T>设置长度,并且进行赋值,即便是这样,在时间效率上ResizeList比ResizeArray要高很多很多。


相关教程