先來一段代碼:
#define MAX_LEN? 10000
int func()
{
int i = 0, j = 0;
int a[MAX_LEN?][MAX_LEN?];
for (i=0; i<MAX_LEN; i++)
{
for (j=0; i<MAX_LEN; j++)
{
a[il[j] = 1;// a[j][i] = 1?
}
}
...
return 0;
}
一般情況下我們都會習慣性的用a[i][j], 如果把a[i][j]換成a[j][i], 功能完全一樣,但效果特別是性能上可能會有十倍甚至百倍的差別,原因何在?
寫到這裏,有的同學可能直接copy代碼編譯測試去了,而採用不同的語言(不同語言的實現要做調整)得到的結果還不一致,有的是a[i][j]好一些,有的則是a[j][i]好一些。
這個問題的核心在於:
在內存使用上,程序訪問的內存地址之間連續性越好,程序的訪問效率就越高;相應地,程序訪問的內存地址之間連續性越差
如果是行優先存儲,就是一行的數據存放在一起,然後逐行存放,那麼a[i][j]的效率要好一些
如果是列優先存儲,就是每一列的數據是存儲在一起的,一列一列地存放在內存中,那麼a[j][i]的效率要好一些
行優先(Row-major)或者列優先(Column-major)取決於編程語言的實現,兩者之間沒有好壞,但其直接涉及到對內存中數據的最佳存儲訪問方式,所以我們在編程的時候要根據編程語言的特別來做針對性的優化,否則同樣的邏輯跑出來的結果會有千差萬別。
佔據編程語言排行榜前幾位的C/C++都是行優先(Java不是行優先也不是列優先,有興趣可以另行研究)