我正在Clojure中编写一个函数来估计解析的JSON的内存大小,如:
(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.PersistentVector
,java.lang.String
等添加开销。
但是,我不确定如何在上面的示例中找到clojure.lang.Keyword
的{{1}}函数的内存大小。 Clojure如何存储关键字?它们的大小是否与C ++ keyword-size
类似,或者它们是enum
的特殊情况,它们取决于长度?
答案 0 :(得分:3)
在Clojure中回答这个问题基本上是不可能的。对于最简单的数据结构,你的第一个草稿函数 okay ,尽管这个最简单的尝试已经有几个错误。
但更重要的是,这只是一个框架错误的问题。此代码段中xs
的大小是多少?
(def xs (let [forever (promise)]
(deliver forever
(lazy-seq (cons 1 @forever)))
@forever))
user=> (take 5 xs)
(1 1 1 1 1)
xs
是一个无限长的序列(因此你的减少将永远不会完成,但如果它能够肯定会返回“这是无限的”)。但它实际上需要一小部分固定的内存,因为它是循环的。
你可能会说,哎这是一个愚蠢的对象,我不介意我的功能是否因为这样的对象而失败。但是,在一种普遍存在的懒惰的垃圾收集语言中,具有相似特征的案例是司空见惯的。如果你排除它们,你就排除了一切有趣的东西。