当前位置: 代码迷 >> ASP.NET >> 2种创建对象的方法,他们的性能区别很大吗?解决方案
  详细解决方案

2种创建对象的方法,他们的性能区别很大吗?解决方案

热度:9416   发布时间:2013-02-25 00:00:00.0
2种创建对象的方法,他们的性能区别很大吗?
如下代码:
方法A、方法B.
2种创建对象的方法,他们的性能区别很大吗?
方法A 是比较靠谱的吧?
C# code
        /// <summary>        /// 查询所有菜品 【方法A】        /// </summary>        /// <returns>返回[IList]</returns>        public static IList<FoodInfo> GetAllFood()        {            IList<FoodInfo> listFood = new List<FoodInfo>(); ;            FoodInfo food= null;//1.创建            string sql = "select FID,F_Pic,F_Desc from FoodInfo order by F_SendTime desc,FID desc";            OleDbDataReader dr=SqlHelper.GetReader(sql)                            while (dr.Read())                {                    food= new FoodInfo();//2.实例化                    food.FID = Convert.ToInt32(dr[0]);                    food.F_Pic = dr[1].ToString();                    food.F_Desc = dr[2].ToString();                    listFood.Add(food);                }                        return listCus;        }

对比下面的
C# code
        /// <summary>        /// 查询所有菜品 【方法B】        /// </summary>        /// <returns>返回[IList]</returns>        public static IList<FoodInfo> GetAllFood()        {            IList<FoodInfo> listFood = new List<FoodInfo>(); ;                        string sql = "select FID,F_Pic,F_Desc from FoodInfo order by F_SendTime desc,FID desc";            OleDbDataReader dr=SqlHelper.GetReader(sql)                            while (dr.Read())                {                    FoodInfo food == new FoodInfo();//1.创建,并且实例化                    food.FID = Convert.ToInt32(dr[0]);                    food.F_Pic = dr[1].ToString();                    food.F_Desc = dr[2].ToString();                    listFood.Add(food);                }                        return listCus;        }


------解决方案--------------------------------------------------------
性能完全一样的,但后一种写法可读性较好,我喜欢后一种写法。
------解决方案--------------------------------------------------------
while (dr.Read())
创建方法都在这里面
每次都会实例化个对象的
------解决方案--------------------------------------------------------
ls说的对啊。

在JAVA里面这样可能会造成内存占用增高,效率不高的情况,但是C#已经在编译期对这部分代码进行了优化。


其实从Java转行的我,还是青睐第一种的,原因是:习惯的适应性。
------解决方案--------------------------------------------------------
C# code
堆栈的内存分配机制对于值类型,一般创建在线程堆栈上。但是值类型作为实例成员的一部分或发生装箱时,值类型是存储在托管堆上的。对于分配在堆栈上的局部变量来说,操作系统维护一个堆栈指针来指向下一个自由空间的地址,并且堆栈的内存地址是由高位到低位向下填充。托管堆的内存分配机制:引用类型的实例分配于托管堆上,而线程栈是对象生命周期开始的地方。32位处理器来说,应用程序完成进程初始化后,CLR将在进程的可用地址空间上分配一块保留的地址空间,它是进程(每个进程可使用4GB)中可用地址空间上的一块内存区域,但并不对应于任何物理内存,这块地址空间即是托管堆。托管堆可划分不同区域:重要的包括垃圾回收堆(GC Heap)和加载堆(Loader Heap),GC Heap用于存储对象实例,受GC管理;Loader Heap最重要的信息就是和元数据相关的信息,也就是Type对象,每个Type在Loader Heap上体现为一个方法表(Method Table,创建于编译时期,主要包含类型的特征信息、实现的接口数目等),Loader Heap不受GC控制,其生命周期是从创建到AppDomain卸载FoodInfo food= null;//声明了一个引用类型的变量food,这不是创建!!!它仅是一个引用(或指针),保村在线程的堆栈上,占4Byte的内存,用于保存FoodInfo对象的有效地址,执行过程是线程栈上的分配过程。此时food为指向任何有效实例,手动初始化为null,试图对food的任何操作将抛出NullReferenceException的异常;while{接着 food= new FoodInfo();通过new操作执行对象创建,该操作对应IL中的newobj指令,执行过程如下:  (a) CLR按照继承关系进行递归搜素,找到System.Object类型,并返回字节总数total(根据你的成员及附加成员的总字节数计算)。  (b) CLR在当前AppDomain对应的托管堆上搜素,找到一个连续未使用的total字节的连续空间      并为其分配地址。注:堆得分配是向高地址扩展,和栈分配时相反的  (c) 如果分配空间时发现内存不足,GC将启动垃圾收集操作来回收垃圾对象所占的内存。  (d)调用构造器,进行初始化操作,完成创建。   (e) 引用指向分配的托管堆地址}这个过程重复利用了一个指针,每次循环的时候都是改变这个指针指向的位置而已while (dr.Read()){                    FoodInfo food == new FoodInfo(); 这个过程先执都会在线程栈上创建一个新的引用,然后(a)(b)(c)(d),然后将新的引用指向分配的托管堆空间}同时,二者的声明的范围不一样
  相关解决方案