Clojure惰性结构的性能与哈希/集合/向量的关系?

问题描述

| 我在各处都使用Clojure数据结构,但没有使用任何惰性计算。在各处使用惰性结构是否会降低性能?     

解决方法

从源代码:
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;
}
因此,您肯定要付出代价。这在很大程度上取决于每个特定的用例,价格对您的影响有多大,以及它是否被内存节省和懒惰的评估买给您的浪费的计算所抵消。     ,惰性结构的开销很大(pmjordan的答案非常适合为您提供血腥的细节.....)。我的粗略估计是您要支付2-5倍的罚款。 但是,还有一些好处: 惰性评估意味着您的工作数据集可能会更小,因为它仅在需要时才创建。在某些情况下,这可以提高缓存利用率,从而提高性能 惰性评估可帮助您编写更简单,更简洁的代码。因此,您可以将注意力集中在编写更好的算法上。拥有更好的算法(例如O(n log n)vs O(n ^ 2))所带来的好处可能比懒惰评估的开销要有价值得多 我的建议是自由使用惰性评估,除非您确定自己确实需要高性能并且负担不起额外费用(例如图像处理等)。