4

文字列のコレクションがあり、4 文字を超えるすべての文字列を最初に短い文字列で並べ替えて返したいとします。

次の行に沿って何かを使用してそれを解決できます。

(def strings ["this" "is" "super" "cool" "everybody" "isn't" "clojure" "great!?!?"])
(sort-by count < (filter #(> (count %) 4) strings))
;; > ("super" "isn't" "clojure" "everybody" "great!?!?")

count2 回使用していることに注意してください。ここではおそらく問題ありませんが、そうでない場合countはどうなりcountますか? countそれを呼び出す代わりにsuper-expensive-function、絶対に必要以上に実行したくない場合はどうなるでしょうか?

そう:

  • 私たちは物事のコレクションを持っています
  • 順序付けられたもののコレクションを返したい
  • 物事ごとに一度だけ呼び出されるべきである、計算コストの高い関数の結果を使用してフィルタリングおよびソートされます

これを行う既存の機能はありますか、それとも独自に構築する必要がありますか?

4

3 に答える 3

8

最も簡単な解決策は、各項目をその計算コストの高いプロパティと組み合わせてから、フィルター処理と並べ替えを行い、パラメーターを破棄することです。

(->> strings
     (map (juxt identity count))
     (filter (fn [[_ c]] (> c 4)))
     (sort-by peek)
     (map first))

問題のプロパティの計算が実際にそれほどコストがかかる場合、ベクトルを割り当てるオーバーヘッドはほとんどなくなるはずです。

于 2013-08-13T06:12:52.200 に答える
1

おそらく、JIT コンパイラーは、この高価な中間結果が 2 つの操作の間でキャッシュ可能であることを理解できるでしょうか? 結果を手動でキャッシュする際の複雑さが増すことを考えると、この可能性を除外してみる価値があります。次のような時間測定を使用して、さまざまなソリューションに対してパフォーマンス テストを数回実行します。

(time (dotimes [_ 1e5] ...))
于 2013-08-13T09:25:20.463 に答える