【发布时间】:2015-03-02 08:55:28
【问题描述】:
我正在开始我的 Elixir 之旅,并正在寻找一些关于如何最好地解决特定问题的建议。
我有一个需要尽快搜索的数据集。数据由两个数字组成,形成一个封闭的波段,以及与每个波段相关的一些元数据。
例如:
From,To,Data
10000,10999,MetaData1
11000,11999,MetaData2
12000,12499,MetaData3
12500,12999,MetaData4
这个数据集可能有超过 100,000 个条目。
我定义了一个 struct 来对数据进行建模,以及一个在内存中创建 Elixir 列表表示的解析器。
defmodule Band do
defstruct from: 0, to: 0, metadata: 0
end
解析器返回Bandstruct 的列表。我定义了一个使用列表理解的find 方法
defp find_metadata(bands, number) do
match? = fn(x) -> x.from <= number and x.to >= number end
[match | _ ] = for band <- bands, match?.(band), do: band
{ :find, band }
end
根据我的新手知识,使用列表推导需要完整遍历列表。为了避免扫描完整列表,我使用了其他语言的搜索树。
Elixir 中是否有可用的算法/机制/方法可以更有效地解决此类搜索问题?
谢谢。
【问题讨论】:
-
Enum.find/2 可能是您想要的(它会遍历一个列表,直到您找到与给定谓词/函数匹配的第一个)。
-
感谢@JoséValim,我担心顺序搜索的时间。在 20K 的搜索空间中,运行 5,000 次搜索并在空间末尾进行匹配,列表理解需要约 1400 毫秒,而 Enum.Find 需要约 1800 毫秒。我使用
mix test --trace来获取时间 - 不确定这是否足够准确? -
在某种程度上(正如@obrok 在下面建议的那样)这不是 Elixir 问题,而是数据结构问题。选择正确的数据结构,您的性能应该会非常出色。
-
@OnorioCatenacci 同意 - 希望确保没有一种语言功能可以帮助处理这种类型的数据结构。
标签: search list-comprehension elixir