Elixir / Erlang 中字符串的长度和大小需要解释
Length and size of strings in Elixir / Erlang needs explanation
谁能解释为什么 s
是一个有 4096 个字符的字符串
iex(9)> s = String.duplicate("x", 4096)
... lots of "x"
iex(10)> String.length(s)
4096
但是它的内存大小只有6个字?
iex(11)> :erts_debug.size(s)
6 # WHAT?!
以及为什么 s2
比 s
短得多
iex(13)> s2 = "1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20"
"1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20"
iex(14)> String.length(s)
50
但是它的大小比s
多了3个字?
iex(15)> :erts_debug.size(s2)
9 # WHAT!?
为什么这些字符串的大小与它们的长度不匹配?
谢谢
第一个线索为什么这表明值可以在 this question 中找到。引用 size/1
文档:
%% size(Term)
%% Returns the size of Term in actual heap words. Shared subterms are
%% counted once. Example: If A = [a,b], B =[A,A] then size(B) returns 8,
%% while flat_size(B) returns 12.
第二条线索可以在Erlang documentation about bitstrings implementation中找到。
所以在第一种情况下,字符串太大,无法单独放在堆上,所以它使用 refc binaries 存储在 stack 上,堆上只有指向给定二进制文件的指针。
在第二种情况下,字符串短于 64 字节,它使用 heap binaries which is just array of bytes stored directly in on the heap, so that gives us 8 bytes per word (64-bit) * 9 = 72
and when we check documentation about exact memory overhead in VM we see that Erlang uses 3..6
words per binary + data
, where data can be shared。
谁能解释为什么 s
是一个有 4096 个字符的字符串
iex(9)> s = String.duplicate("x", 4096)
... lots of "x"
iex(10)> String.length(s)
4096
但是它的内存大小只有6个字?
iex(11)> :erts_debug.size(s)
6 # WHAT?!
以及为什么 s2
比 s
iex(13)> s2 = "1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20"
"1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20"
iex(14)> String.length(s)
50
但是它的大小比s
多了3个字?
iex(15)> :erts_debug.size(s2)
9 # WHAT!?
为什么这些字符串的大小与它们的长度不匹配?
谢谢
第一个线索为什么这表明值可以在 this question 中找到。引用 size/1
文档:
%% size(Term)
%% Returns the size of Term in actual heap words. Shared subterms are
%% counted once. Example: If A = [a,b], B =[A,A] then size(B) returns 8,
%% while flat_size(B) returns 12.
第二条线索可以在Erlang documentation about bitstrings implementation中找到。
所以在第一种情况下,字符串太大,无法单独放在堆上,所以它使用 refc binaries 存储在 stack 上,堆上只有指向给定二进制文件的指针。
在第二种情况下,字符串短于 64 字节,它使用 heap binaries which is just array of bytes stored directly in on the heap, so that gives us 8 bytes per word (64-bit) * 9 = 72
and when we check documentation about exact memory overhead in VM we see that Erlang uses 3..6
words per binary + data
, where data can be shared。