Erlang 从ETS表检索数据

Erlang 从ETS表检索数据,erlang,ets,Erlang,Ets,我知道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,...

我知道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
18>{Time,[[{ok,Binary}]]}=timer:tc(ets,match,[utilo,{a,'$1'}])。
{0,
[{好的,}]}
19> 大小(二进制)。
1759017
从表中检索1.7 MB二进制文件需要0个时间

编辑:看到奥多贝努斯·罗斯马罗斯的答案后,我决定将二进制文件转换为列表。结果如下:

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|...]]]}
1>{ok,B}=file:read_文件(“IMG_2171.JPG”)。
{好的,}
2> 尺寸(B)。
1986392
3> L=二进制到二进制列表(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> 长度(L)。
1986392
5> ets:插入(utilo,{a,L})。
真的
6> 计时器: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 long
list
需要106000微秒,这非常快,不是吗?列表中每个元素有2个单词。因此,数据为4x1.7MB

编辑2:我在erlang问题()上启动了一个线程,结果发现0.1秒相当于执行memcpy()所需的时间(将数据移动到进程堆)。另一方面,Odobenus Rosmarus的回答解释了为什么检索二进制文件需要0时间。

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


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

谢谢您的回答。我尝试了
列表
,检索1986392个长列表花费了106000微秒。很快,回答得好!您的意思是64字节,而不是位:)