更新Erlang ETS表中所有值的最快方法是什么



我想将一个函数应用于ETS表中的所有元组:

表是一个集合,每个键只出现一次。

我的表只包含相同类型的元组:

{Key, X, Y, VX, VY}

所有值均为::integer()

我想做的是有一个特定的值Elapsed并更新所有具有函数apply_vector/2 的我的元组

apply_vector({K, X, Y, 0, 0}, _Elapsed) ->
    {K, X, Y, 0, 0};
apply_vector({K, X, Y, VX, VY}, Elapsed) ->
    NewX = X + (VX * Elapsed),
    NewY = Y + (VY * Elapsed),
    {K, NewX, NewY, VX, VY}.

可能的解决方案

  • 如果我使用ets:foldl,我的插入可以在折叠过程中被遍历,并且导致一个无限(非常长)的循环。

  • 我可以用ets:foldl准备新的元组,然后插入整个列表

  • 我可以插入一个新表,然后用新表替换旧表,但我不想通过调用gen_server,表必须在任何时候都可以访问。

  • 我不能使用ets:update_element,因为我需要读取VX和VY值以更新X和Y。

  • 我知道有一些迭代器实用程序,但似乎没有人允许传递乐趣。

我需要每1-5秒更新一次。因此,维奇的解决方案是有10个元组的效率最高?有100个元组?还有更多?

谢谢!

我保存一份船只列表,关键是船只ID,X和Y是地理位置坐标,VX和VY表示运动矢量:位移一秒钟。Elapsed是一个比率,是自上次以来的秒数使现代化这张表有助于随时了解每艘船的位置。

我可能会使用ets:foldl。

在我看来,你只需要对这些数据进行迭代访问。所以你可以在这里使用记录列表。

另一种方法(我会选择)是设置一个船只管理器,并为每艘船创建一个gen_server。这样,每艘船都会有自己的状态,你实际上不需要遍历任何列表。

同时签出qlchttp://www.erlang.org/doc/man/qlc.htmlqlc让您在ets或mnesia表上使用列表理解。不过,它可能会有与foldl相同的性能。

没有什么好方法可以做你正在做的事情。

最近,我遇到了一个类似的问题(每秒更新约5000行)

这让我采取了一种完全不同的方法
那么,您需要存储解释的值吗?或者您可以在查找时计算值吗?

如何存储:{K、X、Y、VX、VY、LastUpdateTime}

然后做一些类似(不可编译的例子):

boats:get_all() -> % Record syntax would be smarter here, but it's an example...
  ets:foldl(?TABLE,[],fun(Row={Id,_,_,_,_,_},Acc) -> [{Id,calc(Row)}|Acc] end).
boats:get(Id) ->
  [Row] = ets:lookup(?TABLE,Id),
  calc(Row).
calc({_K,X,Y,VX,VY,LastUpdate}) ->
  {X + (VX * (now() - LastUpdate)), Y + (VY * (now() - LastUpdate)}

这使您不必在genserver上进行阻塞,也不必每5秒更新一次表。你基本上只会在每次船只报告时更新表格。

相关内容

  • 没有找到相关文章

最新更新