2011-04-13 108 views

回答

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; 
} 

所以你是絕對是付出代價。它很大程度上取決於每個特定用例的價格對您的影響程度,以及它是否被內存節省和缺乏懶惰評估爲您購買的浪費計算所抵消。

3

有一個懶惰結構的開銷(pmjordan的答案是偉大的給你血淋淋的細節.....)。我非常粗略的估計是你支付2-5倍的罰款。

然而,也有一些上升空間:

  • 懶惰計算意味着數據的工作集可能更小,因爲需要的時候,纔會創建。這可能提高您的緩存利用率,並因此在某些情況下提高性能
  • 延遲評估可幫助您編寫更簡單,更乾淨的代碼。所以你可以專注於編寫更好的算法。擁有更好算法(例如O(n log n)vs O(n^2))的好處可能比懶惰評估的開銷多得多

我的建議是使用懶惰評估除非你確定你處於一種真正需要高性能並且無法負擔開銷的情況下(例如圖像處理或類似的東西....)