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

PHP 超高效統計大檔案行數:分塊讀取法實測 3.14GB 僅 50 秒

     編輯:PHP 綜合知識

痛點

  • file() 一次性載入記憶體,大檔案直接 OOM。
  • fgets() 逐行讀取,IO 系統呼叫過多,極慢。

解決方案:分塊讀取 + substr_count 計算換行符

/**
 * 高效率計算檔案行數
 * @param string $file 檔案路徑
 * @return int 行數
 */
function count_line(string $file): int {
    $fp = fopen($file, 'r');
    if (!$fp) return 0;

    $count = 0;
    $chunkSize = 1024 * 1024 * 2; // 2MB 每塊

    while (!feof($fp)) {
        $data = fread($fp, $chunkSize);
        if ($data === false) break;
        $count += substr_count($data, "\n");
    }

    fclose($fp);
    return $count;
}

實測數據(3.14 GB 檔案,1321 萬行)

執行次數行數耗時
113,214,81056.28 秒
213,214,81049.67 秒

對比:fgets() 逐行讀取同檔案需 20+ 分鐘。

關鍵優化細節

  1. 塊大小調整:2MB 平衡記憶體與系統呼叫次數,SSD 可嘗試 4-8MB。
  2. 換行符兼容:Windows \r\n 會被計為兩行,實際行數需 substr_count($data, "\n");若需精確可先 str_replace("\r\n", "\n", $data)。
  3. 最後一行無換行符:POSIX 定義行以換行符結尾,若檔案末尾無 \n,結果會少 1。可補檢 !feof($fp) && $data !== '' 邏輯。
  4. 編碼無關:僅計算位元組 0x0A,UTF-8/GBK/二進位皆適用。

進階:非阻塞異步統計(Swoole/RoadRunner)

// Swoole 任務異步統計
Swoole\Async::readFile($file, function($filename, $content) {
    $lines = substr_count($content, "\n");
    // 回寫快取或資料庫
});

結語

分塊讀取 + substr_count 是 PHP 單程序統計大檔案行數的最優解,簡單、記憶體常數級、速度接近磁碟順序讀取上限。

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