我正在 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
的内存大小,即上例中的 keyword-size
函数。 Clojure 如何存储关键字?它们是类似于 C++ enum
的常量大小,还是取决于长度的 java.lang.String
的特例?
最佳答案
从 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
是一个无限长的序列(因此您的 reduce 永远不会完成,但如果可以,它肯定会返回“这是无限的”)。但它实际上占用的内存量很小,而且是固定的,因为它是循环的。
你可能会说,哎呀,这是一个愚蠢的对象,我不介意我的函数是否对这样的对象失败。但是在一种普遍存在惰性的垃圾收集语言中,具有类似特征的情况是司空见惯的。如果你排除它们,你就排除了所有有趣的东西。
关于java - Clojure 关键字在内存中的大小是多少?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43286793/