軟體的運作速度必須要在使用者可以接受的範圍內。通常,改善那些短暫的但頻繁使用的例程的速度會大幅提高軟體的整體速度。
要改善速度,當然首先要能夠量度時間。好,那我們考慮一下在跑道上的情況,槍聲一響,馬上按下秒錶開始計時,在選手到達終點那一刻結束計時,這時就可以知道該選手所用的時間了。要開始對下一輪比賽計時前,請先將秒錶歸零。 .NET2.0也提供了這樣一個碼錶:Stopwatch類,它可以比較精確地測量時間。
速度測試:
軟體的效能和可測性是一個複雜的主題。要確保應用程式能夠滿足使用者的期望,就需要在開發週期內考慮它的效能和可測性。這在設計階段至關重要,一個糟糕的設計幾乎肯定會導致糟糕的使用者體驗。然而,僅僅有好的設計也不能保證程式能夠有效率地運行,最終程式碼的品質同樣重要。
量度一個運行時間較長的例程相當簡單。如果一個過程會持續幾分鐘,只要一顆腕錶就可以記錄它的時間了。例如一個執行時間為兩分鐘的過程,10%的改善能夠節省12秒,這是很容易去確定的。
而如果要測量一個非常短暫的過程,就要考慮更好的精確性了。例如有一些很小的例程,它們的運行時間可能只有千分之一秒,但會被呼叫100萬次,這樣的累積效果就很明顯了。在.NET framework的先前版本中,需要使用Windows API函數,而在.NET framework 2.0中,微軟引進了Stopwatch(它就是我們的秒錶)類別來簡化時間的測量任務。
Stopwatch類:
使用Stopwatch類別來量度時間非常簡單。跟現實生活中的秒錶一樣,這個類別的物件也能夠對計數器進行開始、停止、歸零(重置)操作,不過它可比一般的秒錶精確多了,它能夠精確到微秒(也就是百萬分之一秒)。
範例程式碼:
要示範Stopwatch的使用還是來段程式碼吧。下面是一個控制台應用程序,它將1到100萬之間的所有整數累加:
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方法,將繼續計時,最終的計時結果為兩次計時的累積。為避免這種情況,在第二次計時前用Reset方法將物件歸零。這三個方法都不需要參數。代碼是:
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結果:
<!--[if !supportLists]--><!--[endif]--> 在結束計時後下一步就是讀取計時結果了。 Stopwatch類別提供了一下屬性:
<!--[if !supportLists]--><!--[endif]--><!--[if !supportLists]--><!--[endif]-->
Elapsed:傳回一個TimeSpan對象,表示計時時間間隔;
ElapsedMilliseconds:傳回計時經過的微秒數,精準度稍差,適合稍長一點的計時;
ElapsedTicks:傳回計時經過的計時器刻度(timer tick)數。計時器刻度是Stopwatch物件可能的最小量度單位。計時器刻度時間的長度由特定的電腦和作業系統決定。 Stopwatch物件的Frequency靜態欄位的值表示一秒鐘所包含的計時器刻度數。注意它與TimeSpan的Ticks屬性所花費的時間單位的差異。
應根據計時任務的情況來選擇其中的一個屬性。在我們的範例程式中,Elapsed屬性提供了所需的精確度,並用它來輸出經過的微秒數。這也是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方法可以開始一個新的計時器。