【问题标题】:Length and size of strings in Elixir / Erlang needs explanationElixir / Erlang中字符串的长度和大小需要解释
【发布时间】:2018-11-07 02:04:48
【问题描述】:

有人可以解释为什么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!?

为什么这些字符串的大小与它们的长度不匹配?

谢谢

【问题讨论】:

    标签: erlang elixir


    【解决方案1】:

    第一个线索表明为什么可以在this question 中找到值。引用size/1 docs:

    %% 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找到。


    所以在第一种情况下,字符串太大而无法单独放在堆上,所以它使用存储在 stack 上的refc binaries,而在堆上只有指向给定二进制文件的指针。

    在第二种情况下,字符串短于 64 字节,它使用heap binaries,它只是直接存储在堆中的字节数组,所以这给了我们8 bytes per word (64-bit) * 9 = 72,当我们检查有关 VM 中确切内存开销的文档时,我们看到Erlang uses 3..6 words per binary + data, where data can be shared

    【讨论】:

    • 同样重要的是要记住size/1 计数HEAP words。并且链接非常好。谢谢
    猜你喜欢
    • 2023-01-13
    • 2016-01-10
    • 2015-11-06
    • 1970-01-01
    • 2012-12-08
    • 1970-01-01
    • 1970-01-01
    • 2017-01-13
    • 2016-09-18
    相关资源
    最近更新 更多