1. 程式人生 > >例說裝箱與拆箱效能消耗

例說裝箱與拆箱效能消耗

我們一直都知道,C#中的裝箱與拆箱操作存在效能消耗。

並且,泛型的使用能較好的解決這個問題,具體內容請閱讀《》。

今天不上班,閒著無事,寫了段例項程式碼,來看看實際情況又是怎樣。

完整程式碼如下:

using System;
using System.Diagnostics;

namespace BoxExp
{
    class Program
    {
        static void Main(string[] args)
        {
            String str1 = string.Empty;
            String str2 = string.Empty;

//程式碼片段1
           Stopwatch sw1 = new Stopwatch(); 
          sw1.Start();
           for (int i=0; i < 1000000; i++)
           {
               str1 = "Hello," + i;//裝箱操作
           }
            sw1.Stop();
            Console.WriteLine("str1:{0} time:{1}", str1, 1000* sw1.Elapsed.TotalSeconds);

//程式碼片段2
            Stopwatch sw2 = new Stopwatch();
            sw2.Start();
            for (int i = 0; i < 1000000; i++)
            {
                str2 = "Hello," + i.ToString();//無裝箱操作
            }
            sw2.Stop();
            Console.WriteLine("str2:{0} time:{1}", str2, 1000 * sw2.Elapsed.TotalSeconds);           

            object obj = 1;
            int sum1 = 0;
            int sum2 = 0;

//程式碼片段3
            Stopwatch sw3 = new Stopwatch();
            sw3.Start();
            for (int i = 0; i < 1000000; i++)
            {
                sum1 = i + (Int32)obj;//拆箱操作
            }
            sw3.Stop();
            Console.WriteLine("sum1:{0} time:{1}", sum1, 1000 * sw3.Elapsed.TotalSeconds);

//程式碼片段4
            Stopwatch sw4 = new Stopwatch();
            sw4.Start();
            for (int i = 0; i < 1000000; i++)
            {
                sum2 = i + 1;//無拆箱
            }
            sw4.Stop();
            Console.WriteLine("sum2:{0} time:{1}", sum2, 1000 * sw4.Elapsed.TotalSeconds);
        }
    }
}

程式碼中已用註釋標示出哪裡需要裝箱與拆箱操作。

對於裝箱與拆箱不做任何解釋,直接上結果。

確實,存在裝箱操作或者拆箱操作的程式碼耗時比無裝拆箱操作的程式碼耗時要多。上面給出的僅其中一次典型結果。但是每次基本都跟此次結果無太大差距。

順便給出IL程式碼。

程式碼片段1對應的部分IL程式碼

...(省略其他)
  IL_001b:  stloc.3
  IL_001c:  br.s       IL_0035
  IL_001e:  nop
  IL_001f:  ldstr      "Hello,"
  IL_0024:  ldloc.3
  IL_0025:  box        [mscorlib]System.Int32
  IL_002a:  call       string [mscorlib]System.String::Concat(object,object)
...

注意:box 裝箱操作

程式碼片段2對應的部分IL程式碼

 ...
  IL_0084:  stloc.3
  IL_0085:  br.s       IL_009f
  IL_0087:  nop
  IL_0088:  ldstr      "Hello,"
  IL_008d:  ldloca.s   i
  IL_008f:  call       instance string [mscorlib]System.Int32::ToString()
  IL_0094:  call       string [mscorlib]System.String::Concat(string, string)
 ...
                                                           

注意:無box 無裝箱操作

程式碼片段3對應的部分IL程式碼

...
  IL_00fe:  stloc.3
  IL_00ff:  br.s       IL_0112
  IL_0101:  nop
  IL_0102:  ldloc.3
  IL_0103:  ldloc.s    obj
  IL_0105:  unbox.any  [mscorlib]System.Int32
  IL_010a:  add
...

注意:unbox 拆箱操作

程式碼片段4對應的部分IL程式碼

...
  IL_016d:  ldloc.3
  IL_016e:  ldc.i4.1
  IL_016f:  add
  IL_0170:  stloc.s    sum2
  IL_0172:  nop
  IL_0173:  ldloc.3
  IL_0174:  ldc.i4.1
  IL_0175:  add
...

注意:無unbox 無拆箱操作

就到這了。

相關推薦

裝箱效能消耗

我們一直都知道,C#中的裝箱與拆箱操作存在效能消耗。 並且,泛型的使用能較好的解決這個問題,具體內容請閱讀《》。 今天不上班,閒著無事,寫了段例項程式碼,來看看實際情況又是怎樣。 完整程式碼如下:

裝箱效能損耗詳解

拆箱是將引用型別轉換為值型別 ;反之,裝箱! 利用裝箱和拆箱功能,可通過允許值型別的任何值與Object 型別的值相互轉換,將值型別與引用型別連結起來 ; 例如: int val = 100; object obj = val; Cons

日期類時間類,日期時間類,單模式,裝箱,數字類隨機數,BigDecimal總結

方便 下標 時分秒 etime 相等 創建 rep style with 1.日期類,時間類,日期時間類 初步日期使用方法及格式轉換方法(舊方法): 格式://Mon Jul 30 11:26:05 CST 2018 年月日時分秒 CST代表北

裝箱以及效能損失

先分析一下值型別與引用型別 值型別:      Int32 i =4; 【變數i是值型別,被分配在棧上,變數包含變數例項,使用效率高】 引用型別:   object o = i; 【變數o是引用型別,被分配在託管堆,變數包含例項的指標,通過此指標引用其例項】 引用型別效能要比值型別差很多,因此儘量使用值型別

Java SE之裝箱

fin valueof targe 單純 數值 test 構造 簡化 ble 對象包裝器、自動裝箱與拆箱 2016/11/30 晚 特點: 1.所有的基本類型都有一個包裝器類與之對應。[Integer,Boolean,Long,Character,Sh

裝箱的整理

影響 配對 垃圾 多態 one member 轉換 追加 ++ 1、概念:裝箱是將值類型裝換成引用類型的過程;拆箱就是將引用類型轉換成值類型的過程; 2、利用裝箱和拆箱功能,通過允許值類型的任何值與Object類型的值進行相互轉換,將引用 類型與值類型連接起來。 3、

Java中自動裝箱詳解

sans 做的 sys 實例 代碼 而在 byte 裝箱 bsp 在講裝箱與拆箱之前我們要先了解一下這個問題的來源: Java中的類型分為基本類型(Primitive type)和類類型(Class type)兩種: 基本類型包括byte型、char型、short型

詳解Java的自動裝箱(Autoboxing and unboxing)

初始 BE 運算 null 異常 內存 判斷 運行 double 一、什麽是自動裝箱拆箱 很簡單,下面兩句代碼就可以看到裝箱和拆箱過程 1 //自動裝箱 2 Integer total = 99; 3 4 //自定拆箱 5 int totalprim = total;

java中的裝箱

net chan import HA com 裝箱 ava art spa java中的裝箱與拆箱 ,參考這三個博客,寫的很好 1 http://www.importnew.com/15712.html 2 https://www.cnblogs.com/dol

裝箱

對象 nal important 原因 比較 運算符 空指針異常 ros 相同 裝箱與拆箱 什麽是裝箱與拆箱 描述 語言描述,裝箱就是自動將基本數據類型轉換為包裝器類型;拆箱就是自動將包裝器類型轉換為基本數據類型。 代碼描述就是: Integer integer

Java基礎 裝箱

文章轉載自:http://www.cnblogs.com/dolphin0520/p/3780005.html 這篇文章把裝箱與拆箱寫的清晰易懂。以下是正文: 以下是本文的目錄大綱:   一.什麼是裝箱?什麼是拆箱?   二.裝箱和拆箱是如何實現的   三.面試中相關的問題

Java學習筆記之——自動裝箱

自動裝箱與拆箱 基本型別與引用型別的互相轉換 1. 基本型別對應的包裝類 byte    short       char      int &

自動裝箱

Java包裝類、拆箱和裝箱詳解 雖然 Java 語言是典型的面向物件程式語言,但其中的八種基本資料型別並不支援面向物件程式設計,基本型別的資料不具備“物件”的特性——不攜帶屬性、沒有方法可呼叫。 沿用它們只是為了迎合人類根深蒂固的習慣,並的確能簡單、有效地進行常規資料處理。 這種藉助於非面向物件

Java 自動裝箱

什麼是自動裝箱拆箱 基本資料型別的自動裝箱(autoboxing)、拆箱(unboxing)是自J2SE 5.0開始提供的功能。  一般我們要建立一個類的物件例項的時候,我們會這樣:  Class a = new Class(parameter);  當我們建立

2018年11月13日Java學習之包裝類,裝箱

1.將八種基本資料型別定義相應的引用型別—包裝類 這樣做的好處就是可以呼叫類的方法了。 2.裝箱與拆箱 裝箱 int i = 500; Integer t = new Integer(i); 拆箱 boolean b = bObj.booleanValue

C#裝箱

 將值型別轉換為引用型別的過程叫做裝箱,相反,將引用型別轉換為值型別的過程叫做拆箱。 裝箱  :  裝箱允許將值型別隱式轉換為引用型別   從程式結果來看,值型別變數的值複製到裝箱得到的物件中,裝箱後改變值型別變數的值,並不會影響裝箱物件的值

.NET的裝箱內幕

裝箱與拆箱是.NET中非常重要的概念。 裝箱是將值型別轉換成引用型別,或者是實現了介面的值型別。裝箱將資料儲存的空間由Thread stack轉存到了Managed Heap中。凡是在Managed Heap中開闢空間,都將觸發GC(垃圾回收),在Thread statck

4.3 詳解Java的自動裝箱 > 我的程式猿之路:第三十三章

1 //自動裝箱 2 Integer total = 99; 3 4 //自定拆箱 5 int totalprim = total; 簡單一點說,裝箱就是自動將基本資料型別轉換為包裝器型別;拆箱就是自動將包裝器型別轉換為基本資料型別。 下面我們來看看需要裝箱拆箱的型別有哪些: 這個過程是自動執

js的裝箱

 把基本資料型別轉換為對應的引用型別的操作稱為裝箱,把引用型別轉換為基本的資料型別稱為拆箱。1、裝箱,就是用這個值類構造一個相應的包裝物件。如:     var a=10 ,b="javascript" , c=true;    var o_a=new Number(a); 

【C#】裝箱

           在生活中,我們都喜歡吃水果。大家都知道水果不但為我們提供豐富的膳食纖維,還有維生素及其它營養。例如:吃草莓培養耐心補充維生素,吃香蕉保持快樂心情,吃葡萄增強免疫抗衰老,吃梨幫助器