1

フォルダー内の「最も深い」フォルダーへのパスを見つける必要がありました。このために、私は 2 つのアルゴリズムを実装しました。一方は他方よりもはるかに高速です。誰も理由を知っていますか?これにはハードディスクハードウェアとのリンクがあると思いますが、理解したいと思います。これが速いものです:

    private function getHostAux($path) {
        $matches = array();
        $folder = rtrim($path, DIRECTORY_SEPARATOR);

        $moreFolders = glob($folder.DIRECTORY_SEPARATOR.'*', GLOB_ONLYDIR);
        if (count($moreFolders) == 0) {
           $matches[] = $folder;
        } else {
            foreach ($moreFolders as $fd) {
                $arr = $this->getHostAux($fd);
                $matches = array_merge($matches, $arr);
            }
        }
        return $matches;
    }

そして、ここに遅いものがあります:

    /**
     * Breadth-first function using glob
     */
private function getHostAux($path) {
    $matches = array();
    $folders = array(rtrim($path, DIRECTORY_SEPARATOR));
    $i = 0;
    while($folder = array_shift($folders)) {
        $moreFolders = glob($folder.DIRECTORY_SEPARATOR.'*', GLOB_ONLYDIR);
        if (count($moreFolders == 0)) {
            $matches[$i] = $folder;
        }
        $folders = array_merge($folders, $moreFolders);
        $i++;
    }
    return $matches;
}

ありがとう !

4

2 に答える 2

1

観察したこれらの「タイミング」を理解するために重要となる可能性のある追加情報を提供していません。(「遅い」と「速い」の意味と、それをどの程度正確に測定したかを指定していないため、意図的に引用符を作成しました。)

提供された情報が真実であり、最初の方法のスピードアップが数パーセントを超えており、さまざまなサイズと深さのディレクトリでテストしたと仮定します...

まず、提供された回答についてコメントしたいと思います。

  • 私はあなたの答えについてはよくわかりません。まず、「カーネルハンドル」という意味だと思います。globしかし、ハンドルを開かないため、これは当てはまりません。どうやってこの答えを思いついたのですか?
  • 両方のバージョンの合計反復回数は同じです。

そして、自分から何かを追加します。

  • array_shift()呼び出すたびに配列全体のインデックスが再作成されるため、速度が低下する可能性があります。
  • 基盤となるOSとファイルシステムによっては、グロブの順序が重要になる場合があります。
  • コードに(おそらく)バグがあります。$i配列に要素を追加した後ではなく、グロブごとにインクリメントします$matches。これにより、$matches配列がスパースになり、マージ、シフト、または追加プロセスが遅くなる可能性があります。PHPの場合は正確にはわかりませんが、配列にこれらのプロパティがあり、コーディング中に覚えておくのが難しい言語がいくつかあることは知っています。これを修正し、コードのタイミングを再度調整して、違いが生じるかどうかを確認することをお勧めします。
于 2013-01-26T15:54:52.093 に答える
0

再帰を使用した最初のアルゴリズムは、2 番目のアルゴリズムよりも反復回数が少ないと思います。補助変数を使用して、各アルゴリズムが何回反復するかを観察してみてください。

于 2012-10-17T15:46:44.127 に答える