Clojure 真的引起了我的兴趣,我开始阅读它的教程:http: //java.ociweb.com/mark/clojure/article.html
考虑“设置”下提到的这两行:
(def stooges (hash-set "Moe" "Larry" "Curly")) ; not sorted
(def more-stooges (conj stooges "Shemp")) ; -> #{"Moe" "Larry" "Curly" "Shemp"}
我的第一个想法是第二次操作应该需要恒定的时间才能完成;否则,函数式语言可能比面向对象的语言没有什么好处。可以很容易地想象需要从 [几乎] 空集开始,然后在我们进行的过程中填充和缩小它。因此,我们可以将其重新分配给自己,而不是将新结果分配给更多人。
现在,由于函数式语言的奇妙承诺,副作用不再值得关注。所以,集合stooges
并且more-stooges
不应该在彼此之上工作。因此,要么创建more-stooges
是一个线性操作,要么它们共享一个公共缓冲区(如 Java 的StringBuffer
),这似乎是一个非常糟糕的主意并且与不变性相冲突(随后stooges
可以一个接一个地删除一个元素)。
我可能在这里重新发明了一个轮子。当你从最大数量的元素开始,然后一次删除一个直到空集,而不是从一个空集开始并一次增长一个时,似乎hash-set
性能会更高。clojure
上面的例子可能看起来不太实用,或者有解决方法,但是像 Java/C#/Python/etc 这样的面向对象的语言。一次增长或缩小一个或几个元素,同时也可以快速完成。
保证(或只是承诺?)不变性的 [功能] 语言将无法快速增长集合。是否有另一种可以使用的成语以某种方式帮助避免这样做?
对于熟悉的人Python
,我会提到集合理解与等效循环方法。两者的运行时间略有不同,但这与解释器的相对速度有关C
,Python
而不是源于复杂性。我看到的问题是集合理解通常是一种更好的方法,但并不总是最好的方法,因为可读性可能会受到很大影响。
如果问题不清楚,请告诉我。