if vs. switch,測試與分析 (轉)

最近在學php,看php手冊的時候,突然間對if和switch的性能差別有興趣,在網上查了不少資料,最後看到這篇文章,終於讓我發現平時在寫代碼的進候的一個錯誤,喜歡用if ..else多於switch,實際上switch的性能要比if ..else高多了.特引用此文於此,以後寫代碼時候多多注意.

記得在很久以前,博客園上一個哥們抱怨.net的源碼寫的太爛,到處都是switch,我當時就做過一個測試,證實了switch比if性能高許多。今天又看見這個話題,呵呵,那就再做個測試吧。

代碼:


using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;

namespace ConsoleApplication1
{
    
class Program
    
{
        
static Int32 Count = 100000000;

        
static Int32 TestIfElse(Int32 value)
        
{
            Int32 i 
= 0;


            Stopwatch sw 
= new Stopwatch();
            sw.Start();
            
for (int j = 0; j < Count; j++ )
            
{
                
if (value == 1)
                    i 
+= 1;
                
else if (value == 2)
                    i 
+= 2;
                
else if (value == 3)
                    i 
+= 3;
                
else if (value == 4)
                    i 
+= 4;
                
else if (value == 5)
                    i 
+= 5;
            }

            sw.Stop();
            Console.WriteLine(
"TestIfElse: " + sw.ElapsedMilliseconds);
            
return i;
        }


        
static Int32 TestSwitch(Int32 value)
        
{
            Int32 i 
= 0;

            Stopwatch sw 
= new Stopwatch();
            sw.Start();

            
for (int j = 0; j < Count; j++)
            
{
                
switch (value)
                
{
                    
case 1:
                        i
+=1;
                        
break;
                    
case 2:
                        i
+=2;
                        
break;
                    
case 3:
                        i
+=3;
                        
break;
                    
case 4:
                        i
+=4;
                        
break;
                    
case 5:
                        i
+=5;
                        
break;
                    
default:
                        
break;
                }

            }

            sw.Stop();
            Console.WriteLine(
"TestSwitch: " + sw.ElapsedMilliseconds);

            
return i;
        }


        
static void Main(string[] args)
        
{
            TestIfElse(
5);
            TestSwitch(
5);
            Console.Read();
        }

    }

}

 

release下編譯,測試結果:

TestIfElse: 613
TestSwitch: 165

4倍左右的性能差距。反編譯看il,會發現TestSwitch方法中多了這麼一句:

switch (L_0032, L_0038, L_003e, L_0044, L_004a)

這句話實現了一個 jump table。

正如一線工作者 所言,這個switch 指令是一個有索引的跳轉,而if ... else 是無索引的跳轉。if...else 是 O(N)級別的,switch ... case 是 O(1)級別的。

如果將上面測試代碼的分支增加到10支,測試TestSwitch(10)與TestIfElse(10)的性能,會發現前者比後者幾乎快7-8倍。

詳細解釋請參見《深入理解計算機系統》一書中的某章(忘了哪個章節,書不在身邊,裏面講了switch和if的區別)。也可參考這篇文章:http://www.9php.com/FAQ/cxsjl/c/2008/10/1435098132356.html。.net下的分析見:http://www.cnblogs.com/yeah/archive/2009/02/16/1392094.html

如果switch(String ..),測試了一下,switch與if...else性能相當。我原以爲爲是無法生成跳轉表,剛看完http://www.cnblogs.com/yeah/archive/2009/02/16/1392094.html這篇文章,發現還是可以生成跳轉表,只是這個跳轉表的代價比簡單的整數類型的跳轉表代價高。也就是說,這種情況下,switch case 還是O(1)級別分支語句的。

發佈了74 篇原創文章 · 獲贊 1 · 訪問量 29萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章