如何获取 Elixir 中任意数据的大小(以字节为单位)?

Cat*_*ang 1 size byte elixir

似乎没有简单的方法来获取非字符串数据的字节大小?如果我想知道列表、布尔值、整数、浮点等的字节大小,我应该使用什么库?

Ale*_*kin 10

TL;DR不存在术语 \xe2\x80\x9cbyte 大小这样的东西。\xe2\x80\x9d

\n\n
\n\n

由于不变性,在堆中为某些对象共享内存。请参阅下面的示例。

\n\n
\n\n

根据您要寻找的内容,这个答案可能会有所不同。

\n\n

:erlang.term_to_binary/1+:erlang.byte_size/1

\n\n
\n

:erlang.term_to_binary/1Term返回一个二进制数据对象,它是根据 Erlang 外部术语格式 进行编码的结果。\n:erlang.byte_size/1返回一个整数,它是包含Bitstring.

\n
\n\n
> [1] |> :erlang.term_to_binary() |> :erlang.byte_size()\n#\xe2\x87\x92 5\n
Run Code Online (Sandbox Code Playgroud)\n\n

:erlang.external_size/1

\n\n
\n

计算以 Erlang 外部术语格式编码的术语的最大字节大小,而不进行编码。

\n
\n\n
> :erlang.external_size [1]\n#\xe2\x87\x92 5\n\n
Run Code Online (Sandbox Code Playgroud)\n\n

:erts_debug.size/1

\n\n
\n

Term返回实际堆字中的大小。共享子项计算一次。示例:If A = [a,b], B = [A,A]thensize(B)返回8, whileflat_size(B)返回12

\n
\n\n
> :erts_debug.size [1]\n#\xe2\x87\x92 2\n
Run Code Online (Sandbox Code Playgroud)\n\n

附录。内存共享

\n\n

考虑以下示例。

\n\n
t1 = {1, 2}\nm1 = %{a: t1}\nm2 = %{a: t1}\n:erts_debug.same(m1.a, m2.a)\n#\xe2\x87\x92\xc2\xa0true\n
Run Code Online (Sandbox Code Playgroud)\n\n

也就是说,一旦为t1和分配了内存m1m2引用现有对象,并且不会发生进一步的分配(除了标记引用)。

\n\n
\n\n

总而言之,人们需要了解他们对什么尺寸感兴趣。

\n