首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ets选择的性能放缓

ets选择的性能放缓
EN

Stack Overflow用户
提问于 2019-10-31 09:32:56
回答 1查看 576关注 0票数 6

我对ets表的选择性能做了一些测试,并注意到了奇怪的行为。例如,我们有一个简单的ets表(没有任何特定的选项),它存储键/值-一个随机字符串和一个数字:

代码语言:javascript
复制
:ets.new(:table, [:named_table])

for _i <- 1..2000 do
    :ets.insert(:table, {:crypto.strong_rand_bytes(10) 
    |> Base.url_encode64 
    |> binary_part(0, 10), 100})
end

还有一个钥匙已知的条目:

代码语言:javascript
复制
:ets.insert(:table, {"test_string", 200})

现在有一个简单的愚蠢的基准测试函数,它尝试多次从ets表中选择test_string并度量每个选择的时间:

代码语言:javascript
复制
test_fn = fn() ->
  Enum.map(Enum.to_list(1..10_000), fn(x) ->
    :timer.tc(fn() ->
      :ets.select(:table, [{{:'$1', :'$2'}, 
                           [{:'==', :'$1', "test_string"}], 
                           [:'$_']}])
    end)
  end) |> Enum.unzip
end

现在,如果我看一下使用Enum.max(timings)的最大时间,它将返回一个值,这个值大约是所有其他选择的10倍。因此,例如:

代码语言:javascript
复制
iex(1)> {timings, _result} = test_fn.()
....
....
....
iex(2)> Enum.max(timings)
896
iex(3)> Enum.sum(timings) / length(timings)
96.8845

我们可以在这里看到,最大值几乎是平均值的10倍。

这里发生了什么事?它是否与GC、内存分配时间或诸如此类的东西有关?您是否知道为什么从ets表中进行选择有时会造成这样的减速,或者如何对此进行分析。

UPD.

下面是时间分布图:

EN

回答 1

Stack Overflow用户

发布于 2019-11-05 14:03:04

match_specselect/2的第二个论点使它变慢了。

根据这个问题的答案

Erlang: ets select and match performance

代码语言:javascript
复制
In trivial non-specific use-cases, select is just a lot of work around match.  
In non-trivial more common use-cases, select will give you what you really want a lot quicker.

另外,如果您使用的是setordered_set类型的表,要想根据键获得一个值,可以使用lookup/2,因为它要快得多。

在我的电脑上,下面的代码

代码语言:javascript
复制
  def lookup() do
    {timings, _} = Enum.map(Enum.to_list(1..10_000), fn(_x) ->
      :timer.tc(fn() ->
        :ets.lookup(:table, "test_string")
      end)
    end) |> Enum.unzip
    IO.puts Enum.max(timings)
    IO.puts Enum.sum(timings) / length(timings)
  end

已打印

代码语言:javascript
复制
0 
0.0

而你的印刷

代码语言:javascript
复制
16000
157.9

如果您感兴趣,可以在这里找到ets:select的NIF代码。

https://github.com/erlang/otp/blob/9d1b3bb0db87cf95cb821af01189f6d6be072f79/erts/emulator/beam/erl_db.c

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58640319

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档