2017-04-07 49 views
3

我用Clojure寫一個函數來估計內存大小解析的JSON的,是這樣的:Clojure關鍵字的內存大小是多少?

(defn object-size 
    [object] 
    (cond 
    (sequential? object) 
     (reduce + (map object-size object)) 
    (map? object) 
     (reduce 
     (fn [total [k v]] 
      (+ total (keyword-size k) (object-size v))) 
     0 
     object) 
    :else 
     (case (type object) 
     java.lang.Long 8 
     java.lang.Double 8 
     java.lang.String (* 2 (count object)) 
     ;; other data types 
    ))) 

顯然我需要在管理費用增加對clojure.lang.PersistentVectorjava.lang.String

但是,我不確定如何在上面的示例中找到clojure.lang.Keywordkeyword-size函數的內存大小。 Clojure如何存儲關鍵字?它們的大小是否與C++ enum類似,還是它們是依賴於長度的java.lang.String的特例?

+1

對於字符串,您必須考慮您運行的是哪個Java版本。 Java 9對字符串內存AFAIK進行了優化。 另有一個好問題。 – nha

回答

3

從Clojure內部回答這個問題基本上是不可能的。你的第一稿功能好吧爲最簡單的數據結構,雖然這個最簡單的嘗試已經有幾個錯誤。

但更重要的是,這只是一個不良框架的問題。這段代碼中的xs的大小是多少?

(def xs (let [forever (promise)] 
      (deliver forever 
        (lazy-seq (cons 1 @forever))) 
      @forever)) 

user=> (take 5 xs) 
(1 1 1 1 1) 

xs是無限長的序列(所以你的減少將永遠不會完成,但如果可以把它肯定會返回「這是無限的」)。但它實際上需要一個小的固定數量的內存,因爲它是循環的。

你可能會說,很好,這是一個愚蠢的對象,我不介意我的函數是否失敗。但在垃圾收集的普遍懶惰的語言中,具有相似特徵的案例是司空見慣的。如果你排除他們,你排除一切有趣的事情。

+0

這裏的用例是從Youtube,Twitter等分析統計JSONs,這將永遠是相當簡單的。我們將這些統計信息分成批處理進行處理,並且需要了解給定堆大小(這不是很有趣)的批量有多大。我同意這種方法對於最簡單的結構都沒有意義,但這些都是我們需要的。 – bslawski

+1

如果您只需要對JSON結構的大小進行非常粗略的估計,那麼只需取JSON字符串本身的大小即可。如果你想知道有多少物體可以放入內存中以滿足給定的堆大小,*嘗試使用各種批量大小,並查看哪些物體成功。堆中某個特定子項的大小不會非常乾淨地關聯起來。 – amalloy

相關問題