Clojure は本当に私の興味をかき立てたので、それに関するチュートリアルを始めました: http://java.ociweb.com/mark/clojure/article.html
「Set」の下に記載されている次の 2 行を検討してください。
(def stooges (hash-set "Moe" "Larry" "Curly")) ; not sorted
(def more-stooges (conj stooges "Shemp")) ; -> #{"Moe" "Larry" "Curly" "Shemp"}
私が最初に考えたのは、2 番目の操作が完了するまで一定の時間がかかるはずだということでした。そうでなければ、関数型言語はオブジェクト指向言語よりもほとんど利点がないかもしれません。[ほぼ]空のセットから始めて、それにデータを入力して縮小する必要があることは容易に想像できます。したがって、新しい結果をより多くの手先に割り当てる代わりに、それ自体に再割り当てすることができます。
さて、関数型言語のすばらしい可能性により、副作用は気にする必要がなくなりました。そのため、これまでお互いに設定stooges
して動作するべきではありません。more-stooges
したがって、 の作成more-stooges
は線形操作であるか、共通のバッファー (Java の のStringBuffer
ような) を共有しますが、これは非常に悪い考えのように見え、不変性と競合します (その後stooges
、要素を 1 つずつドロップする可能性があります)。
私はおそらくここで車輪を再発明しています。空のセットから始めて一度に 1 つずつ成長させるのではなく、最大数の要素から始めて、空のセットになるまで一度に 1 つずつ削除すると、hash-set
パフォーマンスが向上するようです。clojure
上記の例はあまり実用的ではないように見えたり、回避策があったりするかもしれませんが、Java/C#/Python/etc のようなオブジェクト指向言語. 一度に1つまたはいくつかの要素を拡大または縮小しても問題はなく、高速に実行できます。
不変性を保証する(または約束するだけの)[関数型]言語では、セットをそれほど速く成長させることはできません。それを回避するのに役立つ別の慣用句はありますか?
に精通している人のためにPython
、セット内包表記と同等のループ アプローチについて言及します。2 つの実行時間はわずかに異なりますが、それはC
, Python
, インタープリターの相対的な速度に関係しており、複雑さに起因するものではありません。私が見ている問題は、セット内包表記がより良いアプローチであることが多いということですが、常に最良のアプローチであるとは限りません。
質問が明確でない場合はお知らせください。