.Net最佳實踐3:使用性能計數器收集性能數據

本文值得閱讀嗎?
html

本文討論咱們如何使用性能計數器從應用程序收集數據。咱們將先了解的基本知識,而後咱們將看到一個簡單的示例,咱們將從中收集一些性能數據。less

clip_image001

 

 

介紹: - 個人應用程序的性能是最好的,像火箭
dom

讓咱們這篇文章從一個客戶和開發人員之間的簡短交談開始。函數

 

場景1性能

客戶:- 大家的應用程序的性能怎麼樣?
主觀的開發者:- Well,它真的很快,它是最好的... huuh aaa ooh,它就像火箭同樣。測試

 

場景2網站

客戶:- 大家的應用程序的性能怎麼樣?ui

量化的開發者:- 使用2 GB RAM,xyz處理器和20000客戶記錄的狀況下,客戶屏幕在20秒內加載完成。this

 

我確定比第一個開發的第二個開發者看起來更有前途的。在這篇文章中,咱們將探討咱們如何使用性能計數器來測量應用程序的性能。讓咱們開始計數1,2,3,4 ......es5

 

歡迎下載個人免費的500 Q&A電子書,內容涉及NET,ASP.NET,SQL Server,WCF,WPF,WWF@ http://www.questpond.com . (譯者:做者在原文中作了一些廣告,做爲對他勞動成果的尊重,我將照原文翻譯)


clip_image002

 

感謝Javier和Michael

我真的沒有才智來寫一些關於性能計數器的東西。但閱讀下面的文章中,我能對付着寫一些東西了。所以,首先請容許我感謝這些人,而後咱們再繼續本文。

感謝Javier Canillas建立了performance counter helper,它確實簡化了不少代碼http://perfmoncounterhelper.codeplex.com/

感謝Michael Groeger精彩的文章,我從你的文章中摘取了計數器建立的代碼http://www.codeproject.com/KB/dotnet/perfcounter.aspx

我也從如下文章中摘取了很多內容:

http://msdn.microsoft.com/en-us/library/system.diagnostics.performancecounter.aspx

 

歸根結底,它們是:計數,計算(calculate)和顯示

任何性能評估的工做無外乎計數,計算和顯示。例如,若是你要計算在內存中每秒處理多少分頁,咱們首先咱們須要對處理的頁面的數量和其間流逝的時間(多少秒)進行計數。一旦咱們完成計數,咱們就須要進行計算,如用分頁數除以秒數。最後,咱們須要顯示咱們的性能數據。

clip_image003

 

如今,咱們知道這是一個3步驟的過程,即計數,計算和顯示。計數的部分由應用程序來完成。所以,在計數階段應用程序須要提供數據。請注意,數據不會被性能計數器自動檢測到,而須要應用程序提供一些幫助。而計算和顯示由性能計數器和監視器完成。

clip_image004

 

性能計數器不是魔術師

若是應用程序不提供計數器數據,性能計數器沒法僅憑自身去衡量應用程序性能。性能計數器須要應用程序來提供性能數據用於衡量應用程序。換句話說,應用程序須要經過建立性能計數器對象來提供數據。

 

應用程序性能測量的類型

幾乎全部的應用程序的性能測量屬於如下六大類。

瞬時值:- 不少時候,咱們只是要測量當前值。例如,咱們但願衡量有多少客戶記錄已被處理,有多少RAM內存已被使用等,這些指標被稱爲瞬時值或者絕對值。性能計數器經過瞬時計數器支持這些類型的測量。

平均值:- 有時瞬間/當前值並不展示真實的狀況。例如,只是說應用程序消耗1GB的空間是不夠的。可是,若是咱們可以獲得某種內存消耗的平均數據,如1000個記錄消耗的空間是10MB,也許你能夠更深刻了解應用程序裏面發生了什麼。性能計數器經過使用像AverageBase,AverageTimer32,AverageCount64等類型支持這些種類型的測量。

速率值:- 有些狀況下,當你想知道事件相對於時間的比率。例如,你想知道每秒有多少條記錄被處理。速率計數器幫助咱們計算這些性能指標。

百分比值:- 不少時候,咱們想看到以百分比值來做比較。好比你要比較兩臺計算機之間的性能數據。比較直接的值將不會是一個公平的比較。所以,若是咱們能有兩臺計算機的%值,比較會更有意義。若是咱們要比較不一樣性能計數器的值,百分比是更好的選擇,而不是絕對值。

例如,若是你想把RAM使用狀況和硬盤空間使用狀況作比較。把50GB硬盤使用狀況和1GB RAM的使用狀況作比較,就如同比較蘋果與橘子。若是你使用百分比來表達,這樣的比較更公平和合理。百分比性能計數器能夠幫助咱們以百分比來表達絕對值。

差別值:- 不少時候,咱們但願獲得差值的性能數據,好比從應用程序開始有多少時間流逝,從應用程序開始有多少硬盤消耗。爲了收集這些類型的性能數據,咱們須要記錄原始值和最新值。爲了獲得最終的性能數據,咱們須要從當前值減去原始值。性能計數器提供差值計數器計算這樣的性能數據。

總之,有5種類型的性能計數器,可知足上述全部計數需求。正以下圖所表現的:

clip_image005

 

將用於被性能計數器測試的示例程序

在整篇文章中,咱們將用接下來要說明的一個簡單的程序做爲計數器的例子。在這個例子中,咱們將有一個定時器,每隔100毫秒產生一個隨機數。這些隨機數將被檢查看它是否小於2。若是是,那麼函數‘MyFunction’將被調用。

clip_image006

 

下面的代碼中,計時器將每100毫秒運行一次併產生隨機數,若是隨機數小於2則調用‘MyFunction’函數。

private void timer1_Tick(object sender, EventArgs e)
{
// Generate random number between 1 to 5.
Random objRnd = new Random();
int y = objRnd.Next(1, 5);

// If random number is less than 2 call my Function
if (y > 2)
{
MyFunction();
}
}

 

下面是'MyFunction'函數的代碼,它是當隨機數的值小於2時被調用的。該方法不會作任何事情。

private void MyFunction()
{

}

 

本文中咱們全部的性能計數器的例子,將使用上述定義的代碼示例。

 

 

 

加入咱們的第一個瞬時性能計數器的4個步驟

在咱們深刻‘如何增長一個性能計數器’這個問題以前,讓咱們先來了解一下性能計數器的結構。當咱們建立性能計數器,它須要被加入某些類別。所以,咱們須要建立一個類別,而且把全部性能計數器放在該類別下。

clip_image008

 

咱們來計數‘MyFunction’ 被調用了多少次。首先讓咱們來建立一個名爲「NumberOfTimeFunctionCalled」的即時計數器。在此以前,讓咱們來看看有多少不一樣類型的瞬時計數器被性能計數器所支持: -

一下定義摘自:http://msdn.microsoft.com/en-us/library/system.diagnostics.performancecountertype.aspx

NumberOfItems32- 即時計數器,它顯示最近觀測到的值。

NumberOfItems64- 即時計數器,它顯示最近觀測到的值。 例如,用於維護大量的項或操做的簡單計數。 它與 NumberOfItems32 相同,但它使用更大的字段來容納較大的值。

NumberOfItemsHEX32- 即時計數器,它以十六進制形式顯示最近觀測到的值。 例如,用於維護項或操做的簡單計數。

NumberOfItemsHEX64- 即時計數器,它顯示最近觀測到的值。 例如,用於維護大量的項或操做的簡單計數。 它與 NumberOfItemsHEX32相同,但它使用更大的字段來容納較大的值。

 

1步 建立計數器:- 對於咱們的當前的場景,‘NumberOfItems32’足夠了。因此,咱們首先建立'NumberOfItems32‘即時計數器。有兩種方式,一種是經過代碼,另外一種是使用VS 2008的server explorer來建立計數器。代碼的方法,咱們將在後面看到。如今咱們先使用server explorer來建立咱們的計數器。所以,打開您的Visual Studio,點擊View,打開Server explorer,你會看到下面的圖中所示的「Performance Counters」節點。右鍵單擊「Performance Counters」節點,選擇「create new category」。

clip_image009

 

當咱們建立了一個新的類別,您能夠指定的類別名稱,並在類別中添加計數器。對於當前的例子,咱們給定類別的名稱爲「MyApplication」,而且添加類型爲'NumberOfItem32',名稱爲'NumberOfTimeFunctionCalled」的計數器。

clip_image010

 

 

2步 在你的Visual Studio應用程序中添加計數器:- 一旦你已經把計數器添加到server explorer上,你能夠把計數器控件拖放到ASPX頁面上,以下圖所示。

你須要把只讀」屬性標記爲false,這樣你能夠從代碼中修改計數器的值。

clip_image011

 

 

3步 添加爲計數器計數的代碼:- 最後,咱們須要遞增計數器的值。窗體加載過程當中,咱們首先清除全部計數器的舊值。請注意,計數器的值是做爲全局值保存的,因此他們不會本身重置,須要咱們顯式地重置。所以,在窗體加載時把原始值設置爲零。

private void Form1_Load(object sender, EventArgs e)
{
perfNumberOfTimeFunctionCalled.RawValue = 0;
}

 

當函數被調用時,咱們經過使用‘Increment’方法來遞增計數器的值。每次increment函數的調用,值增長1。

 

private void MyFunction()
{
perfNumberOfTimeFunctionCalled.Increment();
}

 

第4步 查看計數器數據:- 如今,咱們已經指定了計數器在每次‘MyFunction’函數被調用時,遞增其值。如今咱們使用性能監視器(performance monitor)來顯示性能計數器。打開‘Run’並輸入‘perfmon’。你會看到有不少默認的性能計數器,清晰起見,咱們如今刪除全部的計數器,加入咱們的性能計數器即‘NumberofTimeFunctionCalled‘。

clip_image012

 

如今,您能夠看到以下圖所示的圖表。請確保您的應用程序正在運行,由於須要由應用程序發出數據,而後展示在performance monitor上。

clip_image013

 

上述視圖是圖表視圖,要查看相同數據的文本格式,你可使用性能監視器提供的‘view report’選項卡。你能夠看到該報告顯示,從程序開始運行,‘MyFunction的’被調用了9696次。

clip_image014

 

建立更合理的計數器

在前面的章節中,咱們測量了‘MyFunction’被調用的次數。但這樣的性能計數並無真正顯示任何的測量價值。最好是,咱們也能看到計時器被調用次數,而後咱們就可以把計時器被調用的次數和‘MyFunction’被調用的次數作比較。

所以,咱們建立一個即時計數器,當定時器觸發時遞增該計數器。以下面的代碼所示。

private void timer1_Tick(object sender, EventArgs e)
{
perfNumberOfTimeTimerCalled.Increment();
Random objRnd = new Random();
int y = objRnd.Next(1, 5);
if (y > 2)
{
MyFunction();
}
}

 

你能夠在下面的圖表中能夠看到這兩個計數器,藍色的線表示‘MyFunction’被調用的次數,黑色的線表示timer被調用的次數。

clip_image015

 

若是咱們看一下‘report view’,咱們也能夠看到timer被觸發多少次,‘MyFunction’被調用多少次。

clip_image016

 

平均性能計數器

在前面的章節中,咱們用到了2個性能計數器,一個告訴咱們timer被觸發了多少次,另外一個告訴咱們‘MyFunction’被調用了多少次。若是咱們能有某種平均數據,告訴咱們timer每調用一次‘MyFunctionCalled’計數多少次,它將更有意義。

 

爲了獲得這些類型的指標,須要用到平均性能計數器。所以,對於咱們的場景,咱們須要計數函數的調用次數和timer的觸發次數。而後,咱們須要將他們相除,獲得timer每觸發一次函數調用多少次。

clip_image017

 

咱們須要添加兩個計數器,一個做爲分子另外一個做爲分母。對於做爲分子的計數器,咱們須要添加‘AverageCount64’類型的計數器,同時爲分母,咱們須要添加‘AverageBase’類型的計數器。

clip_image018

 

在‘AverageCount64’類型計數器以後,你須要添加‘AverageBase‘計數器,不然,你會獲得一個錯誤,以下圖所示。

clip_image019

 

咱們對於每個timer觸發,咱們都對用於記錄timer調用的計數器進行遞增。

private void timer1_Tick(object sender, EventArgs e)
{
perfAvgNumberofTimeTimerCalled.Increment();
Random objRnd = new Random();
int y = objRnd.Next(1, 5);
if (y > 2)
{
MyFunction();
}
}

 

爲每一次函數調用咱們都對用於記錄函數調用次數的計數器進行遞增

private void MyFunction()
{

perfNumberOfTimeFunctionCalled.Increment();

}

 

若是你運行該程序,在view report模式下你應該會看到以下圖所示。你能夠看到平均‘MyFunction’被調用約0.5次(每timer觸發一次)。

clip_image020

 

若是你本身作計算,你將獲得和性能監視器相同的計算值。

clip_image021

 

 

速率性能計數器

在咱們的示例中,咱們如今想找出‘MyFunction’相對於時間的比率。咱們想知道每秒鐘被調用了多少次。所以,瀏覽server explorer,並添加‘rateofCountsPerSecond32’計數器以下面的圖所示。當‘MyFunction’每次被調用,遞增此計數器。

clip_image022

 

若是您運行的應用程序,你將可以看到「RateofMyFunctionCalledPerSecond」的值。下面是一個簡單的報告,該報告顯示運行15秒後計數器的速率數據。在這15秒中總調用次數爲72次。所以,平均每秒調用5次‘MyFunction’。

clip_image023

 

 

剩下的性能計數器

咱們還剩下百分比計數器和差別計數器,由於他們是很是簡單和直接的,爲了保持本文的焦點和特性,我在文中再也不介紹這兩種計數器


經過C#代碼添加計數器

到如今咱們已經經過server explorer來增長性能計數器。你還能夠經過代碼來添加計數器。第一件事就是,咱們須要導入System.Diagnostics命名空間。

而後,咱們須要建立‘CounterCreationDataCollection’ 對象。

CounterCreationDataCollection Mycounters = new CounterCreationDataCollection();

 

建立實際的計數器並指定計數器的類型。

CounterCreationData totalOps = new CounterCreationData();
totalOps.CounterName = "Numberofoperations";
totalOps.CounterHelp = "Total number of operations executed";
totalOps.CounterType = PerformanceCounterType.NumberOfItems32;
Mycounters.Add(totalOps);

 

最後,在類別中建立計數器。下面的代碼片段用於在‘MyCategory’類別中建立計數器。

PerformanceCounterCategory.Create("MyCategory","Sample category for Codeproject", Mycounters);

 

讓咱們用Performance counter helper來緩解咱們的痛苦

寫性能計數器建立代碼是很痛苦的。使用performance counter helper能夠幫助你緩解這種痛苦並使你的代碼更小巧。你能夠一下網站找到performance counter helper:http://perfmoncounterhelper.codeplex.com/

 

不要在產品中使用

是的,只在開發時使用性能計數器。若是您在產品中使用,確保有一個啓用和禁用機制,不然會影響應用程序的性能。

 

總結

使用性能計數器測量應用程序的數據。
性能計數器包含多種類型,如瞬時,平均,速率等。

性能計數器不該該在產品中用到。若是用到了,確保有一個禁用機制。
性能計數器自身並不能進行測量,它須要應用程序提供數據,這樣性能監視器才能夠計算並顯示的數據。


源代碼

這裏你能夠找到並下載上述性能計數器討論的示例源代碼。

 

其餘最佳實踐

最佳實踐第1部分,請單擊此處

最佳實踐第2部分,請單擊此處

最佳實踐第4部分,請單擊此處

最佳實踐第5部分,請單擊此處

 

個人FAQ文章

(譯者:廣告時間)

我明白這不是談論我FAQ文章正確的地方。只是想稱讚一下本身花費一年時間來完成的FAQ系列。下面是所有的連接:

Silverlight FAQ :- http://www.codeproject.com/KB/WPF/WPFSilverLight.aspx
LINQ FAQ :- http://www.codeproject.com/KB/linq/LINQNewbie.aspx
WWF FAQ :- http://www.codeproject.com/KB/WF/WWF.aspx
WCF FAQ :- WCF.aspx
Sharepoint FAQ :- SharePoint.aspx
Ajax FAQ :- AjaxQuickFAQ.aspx
Architecture FAQ :- SoftArchInter1.aspx
Localization and globalization :- LocalizationGlobalizPart1.aspx
Project management FAQ :- ProjectManagementFAQ.aspx

 

關於做者

Shivprasad koirala

clip_image024

構架師http://www.questpond.com
clip_image025印度

我是微軟ASP / ASP.NET MVP,目前
印度的一家小的E-learning公司的CEO 。咱們很是積極地編寫培訓視頻,寫書和企業培訓。訪問個人網站

.NET, C# , design pattern , WCF , Silverlight
, LINQ , ASP.NET , ADO.NET , Sharepoint , UML , SQL Server  training 
and Interview questions and answers



 

本文由知平軟件劉斌華翻譯,轉載請註明出處。原文地址:http://www.codeproject.com/Articles/42001/NET-Best-Practice-No-3-Using-performance-counters

最佳實踐1和2已經有其餘網友翻譯,一下給出連接:http://www.cnblogs.com/mickeychang/archive/2009/09/17/1568670.html

http://www.cnblogs.com/mickeychang/archive/2009/08/29/1556527.html

 

本人暫時沒有翻譯最佳實踐4和5的計劃。

相關文章
相關標籤/搜索