erlang 为什么escript会输出不同的结果?

slmsl1lt  于 2022-12-08  发布在  Erlang
关注(0)|答案(1)|浏览(209)

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

-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运行射束文件时,它输出与erl相同的结果:

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

发生了什么?我知道 *.beam是编译代码,但是escript在运行它之前没有编译脚本?我还是很困惑。

nukf8bse

nukf8bse1#

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

escript -c processes.erl

你也可以通过在你的脚本中放置指令-mode(compile).来获得这个行为。
the documentation开始:
解释代码的执行速度比编译代码慢。如果大部分执行都是在解释代码中进行的,那么编译它可能是值得的,尽管编译本身会花费一些时间。也可以提供native而不是compile,这将使用native标志编译脚本,这同样取决于脚本的特性,这可能值得或不值得。
如前所述,可以有一个包含预编译的beam代码的脚本。在预编译脚本中,脚本头的解释与包含源代码的脚本中的解释完全相同。这意味着您可以通过在beam文件前面加上以#!和%%!开头的行来使该文件成为可执行文件。在预编译脚本中,必须导出函数main/1。
如果您对预编译选项感兴趣,您可能希望查看构建工具rebar,它有一个escriptize命令,用于将所有代码转换为带有适当escript头的预编译存档。
对于所使用的解释/编译机制,您可以查看the source code to escript。您将看到interpret模式下的escript等效于(以某些语法为模)将代码逐行粘贴到erl交互式解释器中。

相关问题