为什么Elixir Plug使用宏将插件编译到AST中?
如代码所示,插件定义将在宏扩展阶段编译为AST。但是为什么呢?为什么不保留plugs定义并使用为什么Elixir Plug使用宏将插件编译到AST中?,elixir,plug,Elixir,Plug,如代码所示,插件定义将在宏扩展阶段编译为AST。但是为什么呢?为什么不保留plugs定义并使用Enum.reduce\u while或递归逐个调用plugs?我可以想到两个原因: 表演。考虑这两个代码段做相同的事情,但是使用编译函数调用来完成,而另一个使用枚举。Reals< /Cord>和应用< /C> >: defmodule A do def add1(x), do: x + 1 def sub1(x), do: x - 1 def compiled(x) do x
Enum.reduce\u while
或递归逐个调用plugs?我可以想到两个原因:
defmodule A do
def add1(x), do: x + 1
def sub1(x), do: x - 1
def compiled(x) do
x
|> add1()
|> sub1()
|> add1()
|> sub1()
|> add1()
|> sub1()
|> add1()
|> sub1()
end
@pipeline [
{A, :add1},
{A, :sub1},
{A, :add1},
{A, :sub1},
{A, :add1},
{A, :sub1},
{A, :add1},
{A, :sub1}
]
def runtime(x) do
Enum.reduce(@pipeline, x, fn {module, function}, acc ->
apply(module, function, [acc])
end)
end
end
一个简单的基准测试表明,运行时实现的速度慢了5倍
IO.inspect(
:timer.tc(fn ->
for _ <- 1..1_000_000, do: A.compiled(123)
:ok
end)
|> elem(0)
)
IO.inspect(
:timer.tc(fn ->
for _ <- 1..1_000_000, do: A.runtime(123)
:ok
end)
|> elem(0)
)
plug
,而该模块未实现call/2
,则在编译时会出现错误,而不是在运行时执行所有操作时通常会出现的运行时错误82800
433198