【问题标题】:retrieval of data from ETS table从 ETS 表中检索数据
【发布时间】:2012-02-07 08:18:21
【问题描述】:

我知道 ETS 表的查找时间是恒定的。但我也听说表被保留在进程之外,在检索数据时,它需要移动到进程堆中。所以,这很贵。但是,如何解释:

18> {Time, [[{ok, Binary}]]} = timer:tc(ets, match, [utilo, {a, '$1'}]).
{0,
 [[{ok,<<255,216,255,225,63,254,69,120,105,102,0,0,73,
         73,42,0,8,0,0,0,10,0,14,...>>}]]}
19> size(Binary).
1759017

从表中检索 1.7 MB 二进制文件需要 0 时间!?

编辑: 看到 Odobenus Rosmarus 的回答后,我决定将二进制文件转换为列表。结果如下:

1> {ok, B} = file:read_file("IMG_2171.JPG").
{ok,<<255,216,255,225,63,254,69,120,105,102,0,0,73,73,42,
      0,8,0,0,0,10,0,14,1,2,0,32,...>>}
2> size(B).
1986392
3> L = binary_to_list(B).
[255,216,255,225,63,254,69,120,105,102,0,0,73,73,42,0,8,0,0,
 0,10,0,14,1,2,0,32,0,0|...]
4> length(L).
1986392
5> ets:insert(utilo, {a, L}).
true
6> timer:tc(ets, match, [utilo, {a, '$1'}]).
{106000,
 [[[255,216,255,225,63,254,69,120,105,102,0,0,73,73,42,0,8,0,
    0,0,10,0,14,1,2|...]]]}

现在从表中检索 1986392 长 list 需要 106000 微秒,这非常快,不是吗?列表是每个元素 2 个单词。因此数据为 4x1.7MB。

编辑 2:我在 erlang-question (http://groups.google.com/group/erlang-programming/browse_thread/thread/5581a8b5b27d4fe1) 上启动了一个线程,结果发现 0.1 秒几乎是执行 memcpy() 所需的时间(将数据移动到进程的堆)。另一方面,Odobenus Rosmarus 的回答解释了为什么检索二进制文件需要 0 时间。

【问题讨论】:

    标签: erlang ets


    【解决方案1】:

    二进制文件本身(超过 64 位)存储在进程堆之外的特殊堆中。

    因此,从 ets 表中检索二进制文件转移到处理堆只是二进制文件的“Procbin”部分。 (大致是二进制内存和大小中二进制开始的指针)。

    【讨论】:

    • 感谢您的回答。我尝试使用 lists 并检索 1986392 长列表需要 106000 微秒。相当快。
    • 好答案!您的意思是 64 字节而不是位 :)
    猜你喜欢
    • 2021-12-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-22
    相关资源
    最近更新 更多