現在の位置: ホーム> 最新記事一覧> 大きなファイルを処理するときにhash_updateのパフォーマンスを最適化する方法は?

大きなファイルを処理するときにhash_updateのパフォーマンスを最適化する方法は?

gitbox 2025-06-07

大きなファイルを処理する場合、PHPのHash_Update関数は、MD5、SHA-1、より安全なSHA-256などのハッシュ値の計算など、ファイルコンテンツをハッシュするためによく使用されます。ただし、 hash_updateを直接使用すると、主に過剰なメモリ消費またはコンピューティング速度が遅いこととして現れ、大きなファイルのパフォーマンスボトルネックに遭遇する場合があります。この記事では、サンプルコードを使用して、 HASH_UPDATEのパフォーマンスを改善するためのいくつかの効果的な方法を検討します。


1.チャンクを使用してファイルを読み取り、一度に読み込みを避けないでください

ファイル全体をメモリに直接読み取り、それからハッシュすると、メモリオーバーフローまたは非効率性を引き起こす可能性があります。ベストプラクティスは、Chunked Reading Methodを使用して、データをHash_Updateに徐々に渡すことです。

 <?php
$filename = '/path/to/large/file.zip';
$context = hash_init('sha256');

$handle = fopen($filename, 'rb');
if ($handle === false) {
    die('Failed to open file');
}

while (!feof($handle)) {
    $buffer = fread($handle, 8192);  // 8KB それぞれ読みます
    hash_update($context, $buffer);
}

fclose($handle);

$hash = hash_final($context);
echo "File hash: $hash\n";
?>

ここでは、8kBのバッファーサイズが使用されます。これは、システムメモリとIOパフォーマンスに従って調整できます。


2.適切なバッファサイズを選択します

バッファサイズは、読み取りと書き込みのパフォーマンスに直接影響します。小さすぎるとIOの操作が大量になり、大きすぎるとメモリが大きくなります。一般的に言えば、8kbから64kbが良い選択です。 FREADの2番目のパラメーターを調整することで、最高のパフォーマンスをテストできます。


3。PHPビルトイン関数hash_fileを使用して最適化(サポートされている場合)

PHPに付属するHASH_FILE関数は、通常、PHPスクリプトのブロックでブロックを読むよりも、基礎となる実装でより効率的です。ハッシュ値を単に計算するだけの場合は、直接使用することを検討できます。

 <?php
$hash = hash_file('sha256', '/path/to/large/file.zip');
echo "File hash: $hash\n";
?>

この方法では、自分でファイルポインターを管理する必要はなく、パフォーマンスも優れています。


4。並列処理(マルチスレッド/マルチプロセス)

環境が許可されている場合は、ファイルを複数の部分に分割し、複数のプロセスまたは複数のスレッドを使用して各パーツのハッシュを個別に計算し、最後に結果をマージすることができます(部分的ハッシュのカスタマイズやマージなど)。 PHPはマルチスレッドをネイティブにサポートしていませんが、 PCNTL_FORKまたは外部拡張機能で実装できます。

ただし、このソリューションは複雑であり、アルゴリズムの実装をハッシュするための特別な要件があり、通常、特に大きなファイルや特別なシナリオに適しています。


5.繰り返し計算を避け、キャッシュメカニズムを使用します

ファイルが頻繁に変更されない場合、ファイルのハッシュ値をキャッシュして、繰り返し計算を減らすことができます。

たとえば、ファイルの最後の変更時間とハッシュ値を最初に保存します。

 <?php
$filename = '/path/to/large/file.zip';
$cacheFile = '/tmp/file_hash_cache.json';

$cache = json_decode(file_get_contents($cacheFile) ?: '{}', true);
$filemtime = filemtime($filename);

if (isset($cache[$filename]) && $cache[$filename]['mtime'] === $filemtime) {
    $hash = $cache[$filename]['hash'];
} else {
    $hash = hash_file('sha256', $filename);
    $cache[$filename] = ['mtime' => $filemtime, 'hash' => $hash];
    file_put_contents($cacheFile, json_encode($cache));
}

echo "File hash: $hash\n";
?>

これにより、毎回ハッシュが再計算されます。


6.適切なハッシュアルゴリズムを使用します

異なるハッシュアルゴリズムのパフォーマンスは大きく異なります。 MD5とSHA-1は一般にSHA-256よりも高速ですが、安全性は低くなっています。シナリオのトレードオフ速度とセキュリティのニーズに基づいて、適切なアルゴリズムを選択します。


要約します

  • ブロックの読み取り:一度にメモリを読むことを避け、ブロックの読み取りを使用してhash_updateに電話します。

  • バッファサイズを調整します:バッファサイズを合理的に選択して、IOのパフォーマンスを向上させます。

  • HASH_FILE関数を利用:PHPハッシュファイル関数優れたパフォーマンスを備えたハッシュファイル機能。

  • 並列処理:超大型ファイルのマルチプロセスシャード計算を試すことができます。

  • キャッシュハッシュの結果:変更されていないファイルの繰り返し計算を避けてください。

  • 適切なアルゴリズムを選択します。速度とセキュリティのトレードオフに基づいて、ハッシュアルゴリズムを選択します。

これらの手法を習得すると、大きなファイルのハッシュを処理するときにPHPプログラムのパフォーマンスを大幅に改善できます。


 <?php
// サンプルコード:チャンクでファイルを読み、それらを使用します hash_update 計算します SHA-256
$filename = 'https://gitbox.net/path/to/large/file.zip';
$context = hash_init('sha256');

$handle = fopen($filename, 'rb');
if ($handle === false) {
    die('Failed to open file');
}

while (!feof($handle)) {
    $buffer = fread($handle, 65536);  // 64KB
    hash_update($context, $buffer);
}

fclose($handle);

$hash = hash_final($context);
echo "File hash: $hash\n";
?>