2011年7月22日 星期五

Boxing vs. Unboxing

我們常講的型態轉型,譬如說:字串轉數字,這...沒什麼嘛~

但如果突然在書上看到 Boxing vs. Unboxing 時,這....

雖然 Box & Unbox 跟型態轉型有點類似,但實際上還是有一點差別。主要的差別在於轉型的對象,如果你將特定型(如 int,string...)轉換成 object ,這過程就叫做 Boxing ,反之,如果將 object 轉換成特定型別,就叫做 Unboxing 。

在 MSDN 說得很清楚,對大家來說,比較像是名詞定義而已。

int i=123;
object o = (object)i; //boxing

int j=(int)o; //unboxing


不管是執行 Box 還是 Unbox 動作,都是要耗費運算資源的。

以下針對有進行 Boxing 與 沒有 Boxing 進行了比較:


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

namespace boxtest
{
    class Program
    {
        static void Main(string[] args)
        {
            Stopwatch stop = new Stopwatch();

            //啟動計時
            stop.Start();
            List<object> Box = new List<object>();

            //重複 100 萬次
            for (int i = 0; i < 1000000; i++) 
            {
                //進行 Boxing 動作
                Box.Add((object)i);
            }
          
            //停止計時
            stop.Stop();

            //取得耗時數據
            TimeSpan ts = stop.Elapsed;

            //啟動計時
            stop.Reset();
            stop.Start();

            List<int> NoBox = new List<int>();

            //重複 100 萬次
            for (int i = 0; i < 1000000; i++)
            {
                //沒有進行 Boxing
                NoBox.Add(i);
            }
                     

            //停止計時
            stop.Stop();

            //取得耗時數據
            TimeSpan ts2 = stop.Elapsed;


            //列印耗時結果(有 Boxing)
            Console.WriteLine("有Boxing...");
            Console.WriteLine(string.Format("{0:00}:{1:00}:{2:00}:{3:00}",
                ts.Hours, ts.Minutes, ts.Seconds, ts.Milliseconds / 10));


            //列印耗時結果(沒有 Boxing)
            Console.WriteLine("");
            Console.WriteLine("沒有Boxing...");
            Console.WriteLine(string.Format("{0:00}:{1:00}:{2:00}:{3:00}",
                ts2.Hours, ts2.Minutes, ts2.Seconds, ts2.Milliseconds / 10));
            Console.ReadKey();
        }
    }
}




於是可以明確知道,有進行 Boxing 的操作,會比沒有 Boxing 的增加 7 倍運算資源。

參考網址:Boxing 和 Unboxing (C# 程式設計手冊)

程式的沙漏

田徑場上,為了測試運動員的優秀程度,可以透過碼錶來衡量。那你程式寫得好不好,要用什麼來衡量呢?我想,Bug 只是驗證你程式對不對,但「好不好」,可能還真的要拿出碼錶來量一下。

在 C# 裡,還真的有碼錶類別可使用哩!正巧也叫「Stopwatch」。功能也很簡單,大概常會用到的,應該只有啟動(Start)、暫停(Stop)、清除(Reset) 這三項。

以簡單例子來說明:


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

namespace ElapsedTime
{
    class Program
    {
        static void Main(string[] args)
        {
            Stopwatch stop = new Stopwatch();

            //啟動計時
            stop.Start();

            //使用 Thread.Sleep 模擬耗時的程式流程
            Thread.Sleep(10000);

            //停止計時
            stop.Stop();

            //取得耗時數據
            TimeSpan ts = stop.Elapsed;

            //列印耗時結果
            Console.WriteLine(string.Format("{0:00}:{1:00}:{2:00}:{3:00}",
                ts.Hours,ts.Minutes,ts.Seconds,ts.Milliseconds/10));
            Console.ReadKey();
        }
    }
}

日後,如果要比較程式效能時,就可以透過這碼錶取得精確的數據。

參考:Stopwatch 類別

2011年7月14日 星期四

至少要交一個女友

如過要設計個頁面,讓使用者填寫歷任女友姓名,且要判斷至少要填寫一個。這需求很像還蠻簡單的。可以一筆一筆去檢查輸入方塊,只要有值就算通過了。

雖然判斷式一行一行寫不是難事,但卻稍嫌累贅,所以花了些時間想瞭解 jQuery 是否可以處理的更漂亮。於是找到了一個可行的方法,並將他記錄下來!

<html>
<head>
<script src="http://code.jquery.com/jquery-latest.js"></script>
<script>
function CheckNeedOne()
{
   var msg='有值的共有:'+$(".data").filter(function(index){ if($(this).val()=='') return false; return true; }).size();
   if($(".data").filter(function(index){ if($(this).val()=='') return false; return true; }).size()==0)
   { 
 alert(msg+'\n至少要填一項!');
 return false;
   }

   alert(msg);
   return true;
}
</script>
</head>
<body>
<input type="text" id="tbx01" class="data"><br>
<input type="text" id="tbx02" class="data"><br>
<input type="text" id="tbx03" class="data"><br>
<input type="text" id="tbx04" class="data"><br>
<input type="text" id="tbx05" class="data"><br>
<input type="button" value="Send" onclick="return CheckNeedOne();">
</body>
</html>

執行結果:












主要是使用了 jQuery 所提供的 filter(function(index) ) 方法。原先的 $(".data"),讓我取得了5個輸入方塊,再透過 filter( ) 來過濾我所需要的資料。只是這次所要過濾的規則,希望是透過自己所定的規則,判斷輸入方塊是否有值,也就是待會要寫在 function(index) 裡的程式。

在 function(index) 裡,如果目前所檢查的輸入方塊有值,就回傳 true ,反之,則回傳 false。所以就寫成:

if($(this).val()=='') 
  return false; 

return true;

所以,符合 filter(function(index)) 的結果,都是有資料的輸入方塊,最後再透過 .size() 來取得符合的數目,用它來判斷是否大於0,如果沒有的話,就會跳出警告訊息。

$(".data").filter(function(index){ if($(this).val()=='') return false; return true; }).size()
 

希望自己下次再看到這填寫歷任女友的需求時,還會找到更簡潔的作法。

2011年7月13日 星期三

這一定要貼在辦公室門口

員工篇
老闆篇