前言

  最近在看王涛大神的《你必须知道的.NET(第二版)》一书,嗯,首先膜拜一下….
 
  在书中的第五章-品味类型中,对装箱与拆箱一节感触很深,概念本身相信每一个程序猿都不陌生,装箱是将值类型转换为引用类型 ,拆箱是将引用类型转换为值类型(ps:不小心又背了一下书),也知道装箱与拆箱过程中将带来性能上的问题,但是在实际的项目中往往会忽略这个问题,将可能带来极大的效率上的问题。问题有多大,反正我哭过。
 
简单对比测试
  在工作之余写了个简单的测试例子,以HashTable、ArraryList、List<T>进行了简单的对比。
 
  运行环境:Windows7_64(Cpu:i5; Ram:6GB)。
 
  代码如下:
 
复制代码
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
 
namespace Test
{
    /// <summary>
    /// 装箱拆箱(HashTable ArraryList List<T>)对比
    /// </summary>
    class Program
    {
        static void Main(string[] args)
        {
            while (true)
            {
                Console.WriteLine("循环次数:");
                string strcCycleNum = Console.ReadLine();
                int cycleNum = 0;
                if (!int.TryParse(strcCycleNum, out cycleNum))
                {
                    Console.WriteLine("无效输入!");
                    continue;
                }
                HashTableCost(cycleNum);
                ArraryListCost(cycleNum);
                GenericCost(cycleNum);
            }
        }
 
        /// <summary>
        /// HashTable 开销测试
        /// </summary>
        /// <param name="cycleNum">循环次数</param>
        static void HashTableCost(int cycleNum)
        {
            Stopwatch sw = new Stopwatch();
            Hashtable hs_Test = new Hashtable();
            sw.Start();
            for (int i = 0; i < cycleNum; i++)
            {
                hs_Test.Add(i, i);
            }
            sw.Stop();
            ConsoleInfo(cycleNum, "HashTableCost", sw.ElapsedMilliseconds);
        }
 
        /// <summary>
        /// ArraryList 开销测试
        /// </summary>
        /// <param name="cycleNum">循环次数</param>
        static void ArraryListCost(int cycleNum)
        {
            Stopwatch sw = new Stopwatch();
            ArrayList al_Test = new ArrayList();
            sw.Start();
            for (int i = 0; i < cycleNum; i++)
            {
                al_Test.Add(i);
            }
            sw.Stop();
            ConsoleInfo(cycleNum, "ArraryListCost", sw.ElapsedMilliseconds);
        }
 
        /// <summary>
        /// 泛型 开销测试
        /// </summary>
        /// <param name="cycleNum">循环次数</param>
        static void GenericCost(int cycleNum)
        {
            Stopwatch sw = new Stopwatch();
            List<int> lTest = new List<int>();
            sw.Start();
            for (int i = 0; i < cycleNum; i++)
            {
                lTest.Add(i);
            }
            sw.Stop();
            ConsoleInfo(cycleNum, "GenericCost", sw.ElapsedMilliseconds);
        }
 
        /// <summary>
        /// 打印信息
        /// </summary>
        /// <param name="cycleNum">循环次数</param>
        /// <param name="methodName">方法名称</param>
        /// <param name="cost">开销</param>
        static void ConsoleInfo(int cycleNum, string methodName, long cost)
        {
            Console.WriteLine(methodName + " 循环次数:" + cycleNum.ToString() + "  开销(毫秒):" + cost.ToString());
        }
 
    }
}
复制代码
测试结果:
 
测试结果值
 
对于测试结果还是很惊讶,循环添加1000次,3者都为0毫秒,在10W与100W次的结果出现了鲜明的对比分别为305ms,86ms,9ms。差距不是一般的大。
 
对代码进行分析:
 
// HashTable : public virtual void Add(object key, object value); 
// 在Add的过程中进行了2次装箱
 hs_Test.Add(i, i);
HashTable.add()都会产生2次装箱。
 
// public virtual int Add(object value);
// 产生了一次装箱
 al_Test.Add(i);
ArraryList.add产生2次装箱。
 
// 由于lTest 指定了类型(List<int>)并没有产生装箱
lTest.Add(i);
List<int>没有产生装箱。
 
也可以通过IL对代码进行分析,这里就不再列出了。
 
总结
在对大量数据进行操作的时候一定要注意装箱与拆箱操作,可以用泛型代替的地方还是使用泛型吧。
 
在平时的一般项目中的细节也需要注意,毕竟细节决定成败,再NB的框架,也经不起这一片片的装箱与拆箱的轰炸。
 
(ps:隐式转换的时候要细心,在转换成字符串的时候习惯使用ToString(),毕竟是不产生装箱的。)

读书笔记-C#中装箱拆箱性能的更多相关文章

  1. NET中的类型和装箱/拆箱原理

    谈到装箱拆箱,DebugLZQ相信给位园子里的博友一定可以娓娓道来,大概的意思就是值类型和引用类型的相互转换呗---值类型到引用类型叫装箱,反之则叫拆箱.这当然没有问题,可是你只知道这么多,那么Deb ...

  2. CLR via C# 中关于装箱拆箱的摘录

     装箱: 为了将一个值类型转换成一个引用类型,要使用一个名为装箱(boxing)的机制.下面总结了对值类型的一个实例进行装箱操作时在内部发生的事情. 1.在托管堆中分配好内存.分配的内存量是值类型的各 ...

  3. [C#学习笔记]你真的理解拆箱装箱吗?

    学习一项新知识的时候,最好的方法就是去实践它. 前言 <CLR via C#>这本神书真的是太有意思了!没错我的前言就是这个. 装箱 首先来看下,下面这段代码 可以看到,每次循环迭代都会初 ...

  4. Java中的自动装箱拆箱

    Java中的自动装箱拆箱 一.自动装箱与自动拆箱 自动装箱就是将基本数据类型转换为包装类类型,自动拆箱就是将包装类类型转换为基本数据类型. 1 // 自动装箱 2 Integer total = 90 ...

  5. Java中的装箱拆箱

    一)  装箱与拆箱 Java中有概念是一切皆对象,因为所有的类都默认继承自Object.但是,对于数据类型是个例外,如short,int,long,float,double, byte,char,bo ...

  6. 6个重要的.NET概念:栈,堆,值类型,引用类型,装箱,拆箱

    引言 本篇文章主要介绍.NET中6个重要的概念:栈,堆,值类型,引用类型,装箱,拆箱.文章开始介绍当你声明一个变量时,编译器内部发生了什么,然后介绍两个重要的概念:栈和堆:最后介绍值类型和引用类型,并 ...

  7. box unboxing(装箱 拆箱) C#编程指南

    box(装箱)消耗大 box在堆栈中创建一个新的对象,性能消耗大 int i = 123; // Boxing copies the value of i into object o. object ...

  8. .net学习之继承、里氏替换原则LSP、虚方法、多态、抽象类、Equals方法、接口、装箱拆箱、字符串

    1.继承(1)创建子类对象的时候,在子类对象中会为子类对象的字段开辟空间,也会为父类的所有字段开辟空间,只不过父类私有的成员访问不到(2)子类从父类继承父类所有的非私有成员,但是父类的所有字段也会创建 ...

  9. C#装箱拆箱

    .       装箱和拆箱是一个抽象的概念 2.       装箱是将值类型转换为引用类型 :拆箱是将引用类型转换为值类型        利用装箱和拆箱功能,可通过允许值类型的任何值与Object 类 ...

随机推荐

  1. redis 主要数据类型及使用

    1.类型 redis 的主要数据类型: 1.1 string 字符串类型<*是其它4种类型的基础> 1.2 hash 散列类型 1.3 list 列表类型 1.4 set 集合类型 1.5 ...

  2. iOS 9应用开发教程之定制应用程序图标以及真机测试

    iOS 9应用开发教程之定制应用程序图标以及真机测试 定制ios9应用程序图标 在图1.12中可以看到应用程序的图标是网状白色图像,它是iOS模拟器上的应用程序默认的图标.这个图标是可以进行改变的.以 ...

  3. 支撑大规模公有云的Kubernetes改进与优化 (2)

    接下来我们按照kubernetes创建容器的详细过程,以及可能存在的问题. 一.API Server的认证,鉴权,Quota 当客户需要创建一个pod的时候,需要先请求API Server. Kube ...

  4. C++下的强制转换类型

    一.static_cast static_cast,静态类型转换.   下面,我举几个例子,大家就能清楚了. int main(int argc, char const *argv[]) { char ...

  5. [Arc079F] Namori Grundy

    [Arc079F] Namori Grundy 题目大意: 一个有向弱联通环套树. 一个点的sg值等于出边连向点的sg值的mex. 试问是否有办法给每个点分配sg值? 试题分析 题目大意把一些难点跳过 ...

  6. [HDU6212]Zuma

    题目大意: 祖玛游戏. 给你一个01串,你可以往里面加一些0或1,如果连续的0或1超过3个,那么就可以消去.问消去所有的珠子至少要加几个珠子. 思路: 区间DP. 首先把原来的01串,改成存储连续的同 ...

  7. Codeforces Round #350 (Div. 2) B. Game of Robots 水题

    B. Game of Robots 题目连接: http://www.codeforces.com/contest/670/problem/B Description In late autumn e ...

  8. WindowsPhone&amp;Windows8.1&amp;Windows8&amp;Unity3d 填坑日记

    近期的游戏开发大体上接近尾声,总结了不少关于Unity3d面向Windows几大平台开发时遇到的各种坑以及怎样填坑的经验.总的来说,Windows8.1 Windows8/RT以及WindowsPho ...

  9. 74HC245 74HCT245 74LV245 74LVC245 74LVC4245A 74LVC8T245 74LVC16T245 74ALVC164245

    74HC245/74HCT245 The 74HC245; 74HCT245 is a high-speed Si-gate CMOS device and is pin compatible wit ...

  10. 如何在windows server 2008上配置NLB群集

    参考:http://zlwdouhao.blog.51cto.com/731028/781828 前些天写了一篇关于NLB群集模式多播和单播的简单介绍.那么下面我们一起来探讨一下,如何在windows ...