首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

PHP 陣列記憶體優化:以字串模擬陣列大幅降低記憶體佔用

     編輯:PHP 相關知識

PHP 陣列底層為雜湊表,記憶體效率極低(約 1/10)。對於大量數值型資料,可使用 pack()/unpack() 以二進位字串儲存,大幅減少記憶體佔用。

問題背景

  • PHP 陣列每個元素約 48-72 bytes 開銷
  • 100 萬個 double 約需 48-72 MB(C 語言僅 8 MB)
  • 高併發下易觸發 memory_limit 限制

解決方案:二進位字串儲存

<?php
$count = 100000;
$binaryString = '';

// 寫入:以 double 格式打包
for ($i = 0; $i < $count; $i++) {
    $binaryString .= pack('d', $i + 0.1); // 每個 8 bytes
}

// 讀取:按位移解包
for ($i = 0; $i < $count; $i++) {
    $value = unpack('@' . ($i * 8) . '/d', $binaryString);
    // $value[1] 即為第 $i 個數值
}

// 記憶體佔用:約 800 KB(vs 陣列 48 MB+)
echo '字串長度: ' . strlen($binaryString) . ' bytes'; // 800,000
?>

封裝為可複用類別

class BinaryDoubleArray {
    private string $buffer = '';
    private int $count = 0;
    private const ITEM_SIZE = 8; // double = 8 bytes

    public function append(float $value): void {
        $this->buffer .= pack('d', $value);
        $this->count++;
    }

    public function get(int $index): float {
        if ($index < 0 || $index >= $this->count) {
            throw new OutOfBoundsException("Index $index out of range");
        }
        $data = unpack('@' . ($index * self::ITEM_SIZE) . '/d', $this->buffer);
        return $data[1];
    }

    public function count(): int {
        return $this->count;
    }

    public function memoryUsage(): int {
        return strlen($this->buffer);
    }

    // 批次讀取(效能較佳)
    public function getRange(int $offset, int $length): array {
        $format = '@' . ($offset * self::ITEM_SIZE) . '/' . str_repeat('d', $length);
        return array_values(unpack($format, $this->buffer));
    }
}

// 使用範例
$arr = new BinaryDoubleArray();
for ($i = 0; $i < 100000; $i++) {
    $arr->append($i * 1.5);
}
echo "記憶體: {$arr->memoryUsage()} bytes\n"; // ~800KB
echo "第 50000 個: " . $arr->get(50000) . "\n"; // 75000
?>

適用場景與限制

適用不適用
大量數值型資料(float/int)字串、物件、混合型別
順序讀取、隨機存取頻繁插入/刪除中間元素
記憶體受限環境需關聯式鍵值存取
暫存計算中間結果長期持久化(建議用資料庫)

效能權衡

  • 記憶體:降低 90%+
  • 寫入速度:略快於陣列(字串連接)
  • 隨機讀取:較陣列慢(需 unpack 解包)
  • CPU:增加 pack/unpack 運算開銷

此技巧適合「寫一次、讀多次、記憶體敏感」的數值密集型場景,如科學計算、日誌分析、大量感測器資料暫存。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved