gpt4 book ai didi

performance - ets select 的性能下降

转载 作者:行者123 更新时间:2023-12-04 03:07:51 34 4
gpt4 key购买 nike

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

: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

和一个已知 key 的条目:
:ets.insert(:table, {"test_string", 200})

现在有一个简单的愚蠢的基准测试函数试图选择 test_string从 ets 表多次并测量每个选择的时间:
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 倍。因此,例如:
iex(1)> {timings, _result} = test_fn.()
....
....
....
iex(2)> Enum.max(timings)
896
iex(3)> Enum.sum(timings) / length(timings)
96.8845

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

这里发生了什么事?它是否与 GC、内存分配时间或类似的东西有关?您有什么想法为什么从 ets 表中进行选择有时会导致速度变慢或如何对此进行分析。

更新。

这是时序分布图: enter image description here

最佳答案

match_specselect/2 的第二个参数正在使它变慢。

根据对这个问题的回答
Erlang: ets select and match performance

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.

此外,如果您正在处理带有 set 的表或 ordered_set键入,要根据键获取值,请改用 lookup/2,因为它要快得多。
在我的电脑上,以下代码
  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

打印
0 
0.0

虽然你的打印
16000
157.9

如果您有兴趣,可以在此处找到 ets:select 的 NIF C 代码。
https://github.com/erlang/otp/blob/9d1b3bb0db87cf95cb821af01189f6d6be072f79/erts/emulator/beam/erl_db.c

关于performance - ets select 的性能下降,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58640319/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com