大きなファイルを処理する場合、PHPのHash_Update関数は、MD5、SHA-1、より安全なSHA-256などのハッシュ値の計算など、ファイルコンテンツをハッシュするためによく使用されます。ただし、 hash_updateを直接使用すると、主に過剰なメモリ消費またはコンピューティング速度が遅いこととして現れ、大きなファイルのパフォーマンスボトルネックに遭遇する場合があります。この記事では、サンプルコードを使用して、 HASH_UPDATEのパフォーマンスを改善するためのいくつかの効果的な方法を検討します。
ファイル全体をメモリに直接読み取り、それからハッシュすると、メモリオーバーフローまたは非効率性を引き起こす可能性があります。ベストプラクティスは、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パフォーマンスに従って調整できます。
バッファサイズは、読み取りと書き込みのパフォーマンスに直接影響します。小さすぎるとIOの操作が大量になり、大きすぎるとメモリが大きくなります。一般的に言えば、8kbから64kbが良い選択です。 FREADの2番目のパラメーターを調整することで、最高のパフォーマンスをテストできます。
PHPに付属するHASH_FILE関数は、通常、PHPスクリプトのブロックでブロックを読むよりも、基礎となる実装でより効率的です。ハッシュ値を単に計算するだけの場合は、直接使用することを検討できます。
<?php
$hash = hash_file('sha256', '/path/to/large/file.zip');
echo "File hash: $hash\n";
?>
この方法では、自分でファイルポインターを管理する必要はなく、パフォーマンスも優れています。
環境が許可されている場合は、ファイルを複数の部分に分割し、複数のプロセスまたは複数のスレッドを使用して各パーツのハッシュを個別に計算し、最後に結果をマージすることができます(部分的ハッシュのカスタマイズやマージなど)。 PHPはマルチスレッドをネイティブにサポートしていませんが、 PCNTL_FORKまたは外部拡張機能で実装できます。
ただし、このソリューションは複雑であり、アルゴリズムの実装をハッシュするための特別な要件があり、通常、特に大きなファイルや特別なシナリオに適しています。
ファイルが頻繁に変更されない場合、ファイルのハッシュ値をキャッシュして、繰り返し計算を減らすことができます。
たとえば、ファイルの最後の変更時間とハッシュ値を最初に保存します。
<?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";
?>
これにより、毎回ハッシュが再計算されます。
異なるハッシュアルゴリズムのパフォーマンスは大きく異なります。 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";
?>