使用.NET 2.0中的秒表-Stopwatch類進行速度測試

??? 軟件的運行速度必須要在用戶可以接受的范圍內(nèi)。通常,改善那些短暫的但頻繁使用的例程的速度會大幅度地提高軟件的整體速度。
??? 要改善速度,當然首先要能夠量度時間。好,那我們考慮一下在跑道上的情況,槍聲一響,馬上按下秒表開始計時,在選手到達終點那一刻結(jié)束計時,這時就可以知道該選手所用的時間了。要開始對下一輪比賽計時前,要先將秒表歸零。.NET2.0也提供了這樣一個秒表:Stopwatch類,它可以比較精確地測量時間。

??? 速度測試:
??? 軟件的性能和可測性是一個復(fù)雜的主題。要確保應(yīng)用程序能夠滿足用戶的期望,就需要在開發(fā)周期內(nèi)考慮它的性能和可測性。這在設(shè)計階段至關(guān)重要,一個糟糕的設(shè)計幾乎肯定會導(dǎo)致糟糕的用戶體驗。然而,僅僅有好的設(shè)計也不能保證程序能夠高效地運行,最終代碼的質(zhì)量同樣重要。
??? 量度一個運行時間較長的例程相當簡單。如果一個過程會持續(xù)幾分鐘,只要一塊腕表就可以記錄它的時間了。比如一個執(zhí)行時間為兩分鐘的過程,10%的改善能夠節(jié)省12秒,這是很容易去確定的。
??? 而如果要測量一個非常短暫的過程,就要考慮更好的精確性了。比如有一些很小的例程,它們的運行時間可能只有千分之一秒,但會被調(diào)用100萬次,這樣的累積效果就明顯了。在.NET framework的先前版本中,需要使用Windows API函數(shù),而在.NET framework 2.0中,微軟引入了Stopwatch(它就是我們的秒表)類來簡化時間的量度任務(wù)。
??? Stopwatch類:
??? 使用Stopwatch類來量度時間非常簡單。跟現(xiàn)實生活中的秒表一樣,這個類的對象也能夠?qū)τ嫈?shù)器進行開始、停止、歸零(重置)操作,不過它可比一般的秒表精確多了,它能夠精確到微秒(也就是百萬分之一秒)。
??? 示例代碼:
??? 要演示Stopwatch的使用還是來段代碼吧。下面是一個控制臺應(yīng)用程序,它將1到100萬之間的所有整數(shù)累加:

????using?System;

????
namespace?StopWatchClass
????{
????????
class?Program
????????{
????????????
static?void?Main(string[]?args)
????????????{
??????????????? long?total?=?0;

????????????????
for?(int?i?=?1;?i?<=?10000000;?i++)
????????????????{
????????????????????total?
+=?i;
????????????????}
????????????}
????????}
????}
???
??? 添加Stopwatch對象:
??? Stopwatch類位于System.Diagnostics命名空間。下面是添加對象后的代碼:
????using?System;
????
using?System.Diagnostics;

????
namespace?StopWatchClass
????{
????????
class?Program
????????{
????????????
static?void?Main(string[]?args)
????????????{
????????????????Stopwatch?timer?
=?new?Stopwatch();
????????????????
long?total?=?0;

????????????????
for?(int?i?=?1;?i?<=?10000000;?i++)
????????????????{
????????????????????total?
+=?i;
????????????????}
??????????? }
????????}
????}

??? 控制Stopwatch對象:
??? Stopwatch提供了幾個方法用以控制Stopwatch對象。Start方法開始一個計時操作,Stop方法停止計時。此時如果第二次使用Start方法,將繼續(xù)計時,最終的計時結(jié)果為兩次計時的累加。為避免這種情況,在第二次計時前用Reset方法將對象歸零。這三個方法都不需要參數(shù)。代碼是:
????using?System;
????
using?System.Diagnostics;

????
namespace?StopWatchClass
????{
????????
class?Program
????????{
????????????
static?void?Main(string[]?args)
????????????{
????????????????Stopwatch?timer?
=?new?Stopwatch();
????????????????
long?total?=?0;

????????????????timer.Start();
????????????????
for?(int?i?=?1;?i?<=?10000000;?i++)
????????????????{
????????????????????total?
+=?i;
????????????????}

????????????????timer.Stop();

????????????}
????????}
????}

??? 讀取Stopwatch結(jié)果:
?? ?在結(jié)束計時后下一步就是讀取計時結(jié)果了。Stopwatch類提供了以下屬性:
  1. Elapsed:返回一個TimeSpan對象,表示計時時間間隔;
  2. ElapsedMilliseconds:返回計時經(jīng)過的微秒數(shù),精確度稍差,適合于稍長一點的計時;
  3. ElapsedTicks:返回計時經(jīng)過的計時器刻度(timer tick)數(shù)。計時器刻度是Stopwatch對象可能的最小量度單位。計時器刻度時間的長度由特定的計算機和操作系統(tǒng)確定。Stopwatch對象的Frequency靜態(tài)字段的值表示一秒所包含的計時器刻度數(shù)。注意它與TimeSpan的Ticks屬性所用的時間單位的區(qū)別。

    ??? 應(yīng)當根據(jù)計時任務(wù)的情況選擇其中的一個屬性。在我們的示例程序中,Elapsed屬性提供了需要的精確度,用它來輸出經(jīng)過的微秒數(shù)。這也是TimeSpan的最高精確度了。
    ??? 下面是最終的程序代碼:

    ????using?System;
    ????
    using?System.Diagnostics;

    ????
    namespace?StopWatchClass
    ????{
    ????????
    class?Program
    ????????{
    ????????????
    static?void?Main(string[]?args)
    ????????????{
    ????????????????Stopwatch?timer?
    =?new?Stopwatch();
    ????????????????
    long?total?=?0;

    ????????????????timer.Start();
    ????????????????
    for?(int?i?=?1;?i?<=?10000000;?i++)
    ????????????????{
    ????????????????????total?
    +=?i;
    ????????????????}

    ????????????????timer.Stop();

    ????????????????
    decimal?micro?=?timer.Elapsed.Ticks?/?10m;
    ????????????????Console.WriteLine(
    "Execution?time?was?{0:F1}?microseconds.",?micro);
    ????????????}
    ????????}
    ????}


    ??? 另外,使用IsRunning屬性可以查看一個Stopwatch實例是否正在計時,使用StartNew方法可以開始一個新的計時器。

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

    namespace StopWatchClass
    {
    ??? class Program
    ??? {
    ??????? static void Main(string[] args)
    ??????? {
    ??????????? Stopwatch timer = new Stopwatch();
    ???????????
    ??????????? long total = 0;
    ??????????? timer.Start();
    ??????????? //for (int i = 0; i <= 1000000;i++){total = total + i;}
    ??????????? StringBuilder ss = new StringBuilder("你好");
    ??????????? for (int i = 0; i < 100; i++)
    ??????????????? ss.Append("masjkfhkjsadhfkashdfjasdhfkjasdfuirusdg");
    ??????????? timer.Stop();
    ??????????? double micr = timer.Elapsed.TotalMilliseconds;
    ??????????? timer.Reset();
    ??????????? timer.Start();
    ??????????? string s = "你好";
    ??????????? for (int i = 0; i < 100; i++)
    ??????????? {
    ??????????????? s = s + "masjkfhkjsadhfkashdfjasdhfkjasdfuirusdg";
    ??????????? }
    ??????????? timer.Stop();
    ??????????? //NET執(zhí)行效率工具
    ??????????? string micro =Convert.ToString( timer.Elapsed.TotalMilliseconds );
    ??????????? Console.WriteLine(micr + "??? " + micro);
    ??????????? Console.Read();
    ??????? }
    ??? }
    }