設計資料結構節省記憶體的小撇步

以下是三種資料結構,X1 的成員變數亂亂排,X2 由小到大排列,X3 由大到小排列,猜猜看這三種資料結構的大小是多少?

struct X1
{
	char a;     // 1 byte
	int b;      // 4 bytes
	short c;    // 2 bytes
	char d;     // 1 byte
};

struct X2
{
	char a;     // 1 byte
	char d;     // 1 byte
	short c;    // 2 bytes
	int b;      // 4 bytes
};

struct X3
{
	int b;      // 4 bytes
	short c;    // 2 bytes
	char a;     // 1 byte
	char d;     // 1 byte
};

答案如下,有出乎意料之外嗎?

data alignment

這是因為資料對齊的關係,資料對齊則又跟 CPU 存取效能有關,在 X1 結構中是以最大的資料成員,也就是 int (4 bytes) 為對齊方式,因此編譯器會以自然對齊的方式來對齊結構成員去填補結構,如下:

struct X1
{
	char a;		// 1 byte
	char pad0[3];	// 填補對齊到 4 位元組的邊界
	int b;		// 4 bytes
	short c;	// 2 bytes
	char d;		// 1 byte
	char pad1[1];	// 填補對齊到 4 的倍數
};

而結構 X2 及 X3 則有效利用了空間,因此記憶體用量也比較小。

那為什麼要講這個呢?因為在設計看盤軟體的 K 棒資料結構時,如果亂排可是會浪費很多的記憶體的,眾所周知股價資料是很大的,一天可以高達好幾十 GB,因此有必要節省記憶體的用量,以下這兩種設計記憶體用量就差距很大:

struct K1
{
	unsigned long d; // 日期
	double o; // 開
	double h; // 高
	double l; // 低
	double c; // 收
	double v; // 量
	unsigned long t; // 時間
};

struct K2
{
	unsigned long d; // 日期
	unsigned long t; // 時間
	double o; // 開
	double h; // 高
	double l; // 低
	double c; // 收
	double v; // 量
};
不同的 K 棒資料結構大小差距

因此可以的話還是好好排列一下成員變數吧!