最近要分析程式的性能,是以上網查了查資料,的處理下面結論:
#defineARRAYSIZE 2048
voidmain() {
chararrayA[ARRAYSIZE]={0};
chararrayB[ARRAYSIZE];
memset(array,0, ARRAYSIZE);
}
char arrayA[ARRAYSIZE] = {0};
編譯是先arrayA[0]指派為0, 再調用memset初始化其他的數組元素.
效率很難比用memset高,因為綜上分析,我覺得給一塊記憶體指派的效率很難超越memset。
memset
文法:
#include <cstring>void*memset(void*buffer,intch,size_tcount);
memset()拷貝ch至buffer的前count字元中,并傳回buffer。memset()對于以某一值初始化一段記憶體非常有用。例如,這個指令:
constintARRAY_LENGTH=300;charthe_array[ARRAY_LENGTH]; // zero out the contents of the_arraymemset(the_array,'\0', ARRAY_LENGTH);
…是非常有效率的方法來設定the_array中的所有值為零。
下表比較了兩種不同的方式來初始化字元數組:for循環和memeset()。随着初始化資料量的增加,memset()很清晰的做的更快:
耗時for循環memset10000.0160.017100000.0550.0131000000.4430.02910000004.3370.291
變量的初始化
要是極度追求速度的話,“定義變量并嚴格初始化”并不是一條黃金法則,如果流程上并不需要對變量初始化的話。
這取決于你對“初始化”的概念是怎麼了解的。如果你把初始化僅僅了解為變量定義時的初始化的話,那麼“定義變量并嚴格初始化”有時就不是必要的了。例如下面的變量a在定義的時候就不需要對它初始化:
int a = 0; // 這裡的初始化是多餘的,因為它的值從标準輸入裝置讀取。
scanf("%d", &a);
很多人就是把“變量的初始化”了解為“變量定義時的初始化”,進而堅持“定義變量并嚴格初始化”這條規則,這其實是不正确的。這樣做會帶來多餘的初始化,進而降低了效率。從上面看,樓主已經意識到了這個問題,而且正在着手處理。
變量初始化的正确了解應該是“定義的變量第一次有一個給定的值(狀态)”,無論這個值是通過變量定義時的初始化、定義後的指派或者函數參數傳遞等方式得到。有這樣的了解,那麼“定義變量并嚴格初始化”一般情況下就是一條黃金法則(及其特殊的情況下定義變量隻是為了使用它的類型特征,我們不考慮這種情況)。因為定義變量的最終目的就是使用變量(如果不使用它的話,也就不需要定義這個變量了),使用之前變量必須要從程式中得到一個給定值,這樣的使用才是有意義的。
這裡的“變量”可以是一般變量、數組、結構體、類(C++)或者動态配置設定的記憶體空間。
提出幾條不算成熟的建議:
1:非必要情況不對記憶體使用memset清零,尤其是大塊記憶體。
2:如某結構體或記憶體塊在使用前會逐一指派,則不需要對其進行memset初始化。
3:字元串的初始化可以對其第一個位元組指派0。
使用strcpy拷貝的字元串不需要進行初始化。
使用strncpy拷貝的字元串,建議不要先進行memset全部清零,而是在strncpy後,根據字元串實際長度,對字元串後一個位元組置零。
在做流程判斷的時,盡量減少使用字元串比較,而采用整形或布爾量比較。
4:減少結構體轉換和copy代碼。對結構體尤其是包含長字元串的結構體複制時,建議慎用memcpy,而采取逐一指派的方式。
5: 非必要不使用malloc和free,不但容易造成記憶體洩露,而且動态配置設定記憶體快時,系統的記憶體堆狀況可能會影響配置設定效率(比如記憶體碎片很多時)。建議對一些動态配置設定的數組,采用定義一個足夠大的數組方式.(這裡有個問題:局部變量的最大尺寸是多少呢,也就是說程序棧空間是多少呢?這個應該是有限制的,但是每種作業系統或編譯器的限制是多少呢,應該不能在棧空間裡定義一個幾十M或一個G大的數組吧?)
6:unix程式是基本上是以程序模式運作的,可以合理使用全局靜态變量。減少配置設定記憶體的開銷。在多線程程式裡慎用全局變量。
我覺得在寫代碼的時候,不但要把功能實作,該精益求精還是盡量注意,也許确實項目組裡開發的時候對代碼品質細節控制不是很嚴格吧。