用一個 bit 標記某個整數是否存在。32 個整數僅佔 1 個 32 位整數(4 字節)。百萬整數約需 128KB(1,000,000 / 8 / 1024 ≈ 122KB),極大節省內存。
class bigMap {
private $mask = 0x1f; // 31 = 0b11111,用於取模 32
private $bitsperword = 32;
private $shift = 5; // 2^5 = 32,右移 5 位等同除以 32
public $bitArray = [];
// 清除位(置 0)
function clearbit($i) {
@$this->bitArray[$i >> $this->shift] &= ~(1 << ($i & $this->mask));
}
// 設置位(置 1)
function setbit($i) {
@$this->bitArray[$i >> $this->shift] |= (1 << ($i & $this->mask));
}
// 測試位
function testbit($i) {
return $this->bitArray[$i >> $this->shift] & (1 << ($i & $this->mask));
}
}
// 測試
$oBig = new bigMap();
$oBig->setbit(30);
var_dump($oBig->testbit(2)); // false
var_dump($oBig->testbit(30)); // true
var_dump($oBig->bitArray); // [1073741824] (bit 30 置 1)
echo decbin($oBig->bitArray[0]), "<br>"; // 100000000000000000000000000000
$i >> 5:得出數組下標(每 32 個整數一個元素)。$i & 31:得出元素內的位偏移(0~31)。1 << offset:生成只有該位為 1 的掩碼。| 置 1,& ~mask 置 0,& mask 測試。| 數據量 | 位圖內存 | PHP 陣列內存(估算) |
|---|---|---|
| 10 萬 | ~12 KB | ~8 MB |
| 100 萬 | ~122 KB | ~80 MB |
| 1 億 | ~12 MB | ~8 GB |