【问题标题】:Why does escript outputs different result?为什么 escript 输出不同的结果?
【发布时间】:2021-01-30 22:50:41
【问题描述】:

这是一个简单而著名的测试脚本:

-module(processes).
-compile(export_all).

max(N)->
    Max=erlang:system_info(process_limit),
    io:format("the max processes is ~p ~n",[Max]),
    statistics(runtime),
    statistics(wall_clock),
    L=for(1,N,fun()->spawn(fun()->wait() end) end),
    {_,Time1}=statistics(runtime),
    {_,Time2}=statistics(wall_clock),
    lists:foreach(fun(Pid)->Pid!die end,L),
    U1=Time1*1000/N,
    U2=Time2*1000/N,
    io:format("the proecess time is ~p:~p ~n",[U1,U2]).

wait()->
    receive
        die->void
    end.

for(N,N,F)->[F()];
for(I,N,F)->[F()|for(I+1,N,F)].

main([])->
    max(100000).

这是erl的输出:

$ erl 
Erlang/OTP 17 [erts-6.2] [source] [64-bit] [smp:2:2] [async-threads:10] [kernel-poll:false]

Eshell V6.2  (abort with ^G)
1> c(processes)
1> processes:max(100000).
* 2: syntax error before: processes
1> c(processes).         
{ok,processes}
2> processes:max(100000).
the max processes is 262144 
the proecess time is 1.1:4.35 
ok

这是escript的输出:

$ escript processes.erl
the max processes is 262144 
the proecess time is 47.8:83.4

escript 和 erl 之间的确切区别是什么? 我是erlang的新手,请帮忙!

编辑:

escript运行beam文件时,输出和erl一样的结果:

$ escript processes.beam
the max processes is 262144 
the proecess time is 1.8:3.33

会发生什么?我知道 *.beam 是编译代码,但是 escript 在运行之前不编译脚本吗?我还是一头雾水。

【问题讨论】:

    标签: erlang escript


    【解决方案1】:

    不同之处在于您的第二次运行被解释,而您的第一次运行被编译。运行

    escript -c processes.erl
    

    你会得到一个基本相同的时间。您还可以通过将指令 -mode(compile). 放入脚本中来获得此行为。

    来自the documentation

    解释代码的执行比编译代码慢。如果大部分 执行发生在解释代码中,可能值得 编译它,即使编译本身需要一点时间 尽管。也可以提供本机而不是编译,这 将使用本机标志编译脚本,再次取决于 脚本的特征这可能值得,也可能不值得。

    如前所述,可以有一个脚本包含 预编译的梁代码。在预编译脚本中,解释 脚本头与包含源代码的脚本完全相同 代码。这意味着您可以通过以下方式使梁文件可执行 在文件前面加上以 #! 开头的行和 %%!提及 以上。在预编译脚本中,必须导出函数 main/1。

    如果您对预编译选项感兴趣,您可能需要查看构建工具rebar,它有一个escriptize 命令,用于将您的所有代码转换为带有适当escript 标头的预编译存档。

    使用的解释/编译机制可以查看the source code to escript。您将看到interpret 模式下的 escript 等效于(以某些语法为模)将您的代码逐行粘贴到 erl 交互式解释器中。

    【讨论】:

    • 感谢您的详细回答! erlang vm中代码的确切表示是什么?无论如何,我认为源文件会像其他语言一样转换为字节码,例如Python。编译意味着字节码转换?然后我认为escript无论如何都必须在运行之前完成。
    • 我添加了更多细节。我相信 Python 在运行之前会编译(默认为类似 escript 的 -c 模式)。我怀疑在现代 PC 或更快的 PC 上,编译成本是如此之小,以至于您总是希望在运行之前编译您的 escripts(因为大多数时候它会花费几毫秒,偶尔会节省几秒钟)。跨度>
    猜你喜欢
    • 2018-01-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多