使用合理的內存訪問方式
一、你需要開辟一段內存來存放和管理一個4 x 4的矩陣,並單位化之。
不合理:
int aMatrix[4][4];
for ( int i = 0; i < 4; i++ )
{
for ( int j = 0; j < 4; j++ )
{
if ( i == j )
{
aMatrix[i][j] = 1;
}
else
{
aMatrix [i][j] = 0;
}
}
}
合理:
int aMatrix[4 * 4];
for ( int i = 0; i < 4; i++ )
{
for ( int j = 0; j < 4; j++ )
{
if ( i == j )
{
aMatrix[ i * 4 + j ] = 1;
}
else
{
aMatrix [ i * 4 + j ] = 0;
}
}
}
解析:
在任何時候都要避免使用多維數組,數組維數的增加,相應的程序復雜度將會以幾何級數的方式增加,也更加的難於理解。
二、你需要對上面那個矩陣賦值,使它從左上角向右下角按先縱後橫的順序給它賦值
不合理:
for( int i = 0; i < 4; i++ )
{
for ( int j = 0; j < 4; j++ )
{
aMatrix[ j * 4 + i ] = i * 4 + j;
}
}
合理:
for( int i = 0; i < 4; i++ )
{
for ( int j = 0; j < 4; j++ )
{
aMatrix[i * 4 + j ] = j * 4 + i;
}
}
解析:
盡量保證順序的訪問數組的每一個元素。由於Windows內存的管理模式,內存是分頁管理的。順序訪問數組可以基本保證頁面不會來回切換,從而減少了頁失效的數量,提高了程序的整體性能。這種性能的提升對於大的數組尤為明顯。
三、你需要用3個float值來表示一個三維的點,並要寫一個函數對一個三維點的數組進行計算賦值。
不合理:
void foo( float *pPoints[3] )
{
float aPoint[3] = { 1.0f, 2.0f, 3.0f };
int nCount = (int)_msize( pPoints );
for ( int i = 0; i < nCount; i++ )
{
pPoints[i][0] = aPoint[0];
pPoints[i][1] = aPoint[1];
pPoints[i][2] = aPoint[2];
}
}
合理:
struct POINT3
{
float x, y, z;
};
void foo( POINT3 *pPoints, int nCount )
{
POINT3 Pt = { 1.0f, 2.0f, 3.0f };
for ( int i = 0; i < nCount; i++ )
{
pPoints[i] = Pt;
}
}
解析:
有兩點,一,不要使用_msize對數組的大小進行測定,_msize只能對使用malloc或calloc申請的內存進行大小測定,對於其它的如new或一些API,將會導致程序的崩潰。在設計此類需要傳入數組的函數時,別忘了把數組的元素數量也做為參數一並傳入,哪怕它是固定的,這將是一個良好的習慣。二,對於float[3]這種類型,盡量避免直接使用它,最好的辦法就是用struct對其進行簡單的封裝,在復制的時候直接使用“=”就可以進行准確的按位賦值了。
四、你有一個函數的定義,在這個函數中會new一個比較大的對象Data,並在計算後將它刪除。但這個函數將被頻繁調用。
不合理:
void foo( void )
{
Data *p = new Data;
CalcData( p );
delete p;
}
合理:
char Buf[sizeof(DATA)];
void foo( void )
{
Data *p = new(Buf) Data;
CalcData( p );
}
解析:
new(buf) type;是定位的new語法,它不會真正的分配內存,而是簡單的在指定的已分配的內存起點上劃分出一段與類型大小匹配的空間,並直接在這段內存上對該類型進行構造對象,並返回對象的指針。由於它沒有真正的分配內存空間,因此它的效率是非常高的,在類似於上述例程中,頻繁申請和釋放一個大對象的操作,定位的new可以帶來很大的效率提升。