Clojure懒惰结构与哈希/集/向量的表现?

时间:2011-04-13 07:42:52

标签: clojure

我正在使用Clojure数据结构,但我没有使用任何惰性评估。在任何地方使用惰性结构会有性能损失吗?

2 个答案:

答案 0 :(得分:4)

来自源代码:

clojure.lang.Cons(严格的列表元素,clojure.lang.PersistentList非常相似),https://github.com/clojure/clojure/blob/1.2.0/src/jvm/clojure/lang/Cons.java#L34

public Object first(){
    return _first;
}

clojure.lang.LazySeq(懒惰序列元素),https://github.com/clojure/clojure/blob/1.2.0/src/jvm/clojure/lang/LazySeq.java#L77

public Object first(){
    seq();
    if(s == null)
        return null;
    return s.first();
}

,其中

final synchronized Object sval(){
    if(fn != null)
        {
        try
            {
            sv = fn.invoke();
            fn = null;
            }
        catch(Exception e)
            {
            throw new RuntimeException(e);
            }
        }
    if(sv != null)
        return sv;
    return s;
}

final synchronized public ISeq seq(){
    sval();
    if(sv != null)
        {
        Object ls = sv;
        sv = null;
        while(ls instanceof LazySeq)
            {
            ls = ((LazySeq)ls).sval();
            }
        s = RT.seq(ls);
        }
    return s;
}

所以你肯定付出了代价。它在很大程度上取决于每个特定的用例,这个价格对你有多大影响,以及它是否被内存节省和懒惰评估所带来的浪费计算所抵消。

答案 1 :(得分:3)

懒惰结构的开销(pmjordan的回答非常适合给你血腥的细节......)。我非常粗略的估计是你付了2-5倍的罚款。

然而,也有一些好处:

  • 延迟评估意味着您的工作数据集可能更小,因为它仅在需要时创建。在某些情况下,可能可以提高缓存利用率,从而提高性能
  • 懒惰评估可帮助您编写更简单,更清晰的代码。因此,您可以将注意力集中在编写更好的算法上。拥有更好的算法(例如O(n log n)vs O(n ^ 2))的好处可能比延迟评估的开销更有价值

我的建议是自由使用懒惰评估,除非您确定自己处于真正需要高性能且无法负担开销的情况下(例如图像处理或类似的东西......)