问题描述
|
我在各处都使用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))所带来的好处可能比懒惰评估的开销要有价值得多
我的建议是自由使用惰性评估,除非您确定自己确实需要高性能并且负担不起额外费用(例如图像处理等)。