我有一个很大的map
,我使用理解创建组合,然后过滤组合......
for a <- data[:a],
b <- data[:b],
c <- data[:c],
reducer(a ++ b ++ c) <= @limit do
a ++ b ++ c
end
据我所知,这不是并行完成的,只使用一个核心(?)
所以,我想在此添加Flow
,以便在创建组合时,可以并行过滤它们。
以下是一个由3个功能组成的模块:
CompFlow.no_flow
:没有流量,只是使用理解CompFlow.enum_flow
:使用理解创建Enum
,然后使用流程过滤CompFlow.stream_flow
:将组合创建为Stream
,并在创建流时过滤它们......我想 我认为这些功能中的每一个都应该比下一个功能更快,但事实恰恰相反...... no_flow
比enum_flow
快一个数量级比stream_flow
快几个数量级。
我显然对如何申请流量有一个根本的误解...有人可以解释我在这里做错了什么,如果我想做什么(加快理解力)是可能的?
完整模块:
defmodule CompFlow do
@moduledoc false
require Logger
@limit 9
@data %{
:a => [
[{1, "a"}, {2, "b"}],
[{5, "w"}, {4, "x"}],
[{1, "y"}, {3, "z"}]
],
:b => [
[{1, "a"}, {2, "b"}],
[{3, "i"}, {3, "j"}],
[{2, "e"}, {1, "f"}]
],
:c => [
[{1, "g"}],
[{3, "s"}],
[{3, "v"}]
]
}
@doc """
Create and filter combos with a comprehension.
"""
def no_flow(data \\ @data) do
Logger.info "Starting to create combos"
combos = for a <- data[:a],
b <- data[:b],
c <- data[:c],
reducer(a ++ b ++ c) <= @limit do
a ++ b ++ c
end
Logger.info "Combos created"
end
@doc """
Create all combos, then filter the resulting
`Emun` using a `Flow`.
"""
def enum_flow(data \\ @data) do
Logger.info "Starting to create combos"
combos = for a <- data[:a],
b <- data[:b],
c <- data[:c] do
a ++ b ++ c
end
filtered_combos = combos
|> Flow.from_enumerable()
|> Flow.partition()
|> Flow.reduce(fn -> [] end,
fn x, acc ->
if reducer(x) <= @limit do
acc ++ [x]
else
acc
end
end)
|> Enum.to_list()
Logger.info "Combos created"
end
@doc """
Create combos and filter the `Stream` using
a `Flow`.
"""
def stream_flow(data \\ @data) do
Logger.info "Starting to create combos"
combos = for a <- data[:a],
b <- data[:b],
c <- data[:c] do
[a ++ b ++ c]
|> Flow.from_enumerable()
|> Flow.partition()
|> Flow.reduce(fn -> [] end,
fn x, acc ->
if reducer(x) <= @limit do
acc ++ x
else
acc
end
end)
|> Enum.to_list()
end
filtered_combos = Enum.filter(combos, &(length(&1) > 0))
Logger.info "Combos created"
end
defp reducer(enum) do
Enum.reduce(enum, 0, fn(x, acc) -> elem(x, 0) + acc end)
end
end
答案 0 :(得分:0)
您的地图太小,无法从使用Flow中获益。在处理非常大的甚至无限期集合时,流程非常棒,因为这样可以在几个核心上运行应用程序。但是,Flow需要一些时间来初始化,并且后台的整个操作也需要一些时间,所以在你的情况下使用它是没有意义的。
您应该尝试使用Enum
模块优化方法 - 对于这样的小地图,此模块就足够了。您可以更改合并列表的方式而不是
a ++ b ++ c
你可以使用更高效的东西。
每当你使用这个组合列表时,你应该从变量中获取它 - 而不是一直计算它。
请watch more here了解Flow所需的开销。