2

私はclojureでWebクローラーをプログラミングしていますが、関数に与える深さに関係なく一定の時間がかかります。これは関数そのものです。(clojureスープを使用していますが、関係ないと思います)

(defn crawl [source current-depth max-depth]
    (if (= current-depth 0) (write-to-hf "{" false))
    (let [targets (get-links source)]
        (write-to-hf (str ":" source " " (seq targets) "\n") true)
        (if (< current-depth max-depth)
            (map crawl targets (repeat (inc current-depth)) (repeat max-depth))
            (if (= current-depth 0)
                (do (write-to-hf "}" true)
                 targets)
                targets))))

(write-to-hfはデータをファイルに書き込む関数なので、問題にも関係ないと思います。)

REPLで関数をテストしたとき、次のように記述しました。

(crawl "http://bg.wikipedia.org" 0 1)

すべてのリンクを印刷するのに約1時間かかりますが、結果をvarに入れると、1秒もかかりません。

(def a (crawl "http://bg.wikipedia.org" 0 1))

I / O操作は最も時間がかかるため、これは私には正常に見えますが、再帰の深さの層が多いvarに結果を入れるのにかかる時間をテストしようとしましたが、一定のようです。でも:

((crawl "http://bg.wikipedia.org" 0 100000000000))

同じ時間がかかります。

なぜこれが一定なのか誰かが私に説明できますか?ウィキペディア(すべてのページに数百のリンクがある巨大なWebサイト)から数十億以上のページからリンクを取得する方法を1秒以内に実行できるとは想像できません。

4

1 に答える 1

6

この行は、クロールされたリンクの遅延シーケンスを生成しています。

(map crawl targets (repeat (inc current-depth)) (repeat max-depth))

実際のクロールは、リンクが(この場合はREPLによって)印刷されるときに発生するため、それらをvarに保存し、それらを見ない場合、作業は行われません。何もしないと、ほぼ一定の時間がかかります。その行を呼び出しでラップして、doall遅延しないようにします

于 2013-01-23T18:46:06.300 に答える