1

It's a simple and well-known test script:

-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).

Here is the output of 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

Here is the output of escript:

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

What's the exact difference between escript and erl? I'm a newbie of erlang, please help!

Edit:

When escript runs beam file, it output same result as erl:

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

What happens? I know *.beam is compiled codes, but escript does not compile the script before running it? I'm still confused.

2240
  • 1,547
  • 2
  • 12
  • 30
kingluo
  • 1,679
  • 1
  • 13
  • 31

1 Answers1

1

The difference is that your second run is being interpreted, while your first run was compiled. Run

escript -c processes.erl

and you'll get a time that is basically the same. You can also get this behavior by putting the directive -mode(compile). in your script.

From the documentation:

Execution of interpreted code is slower than compiled code. If much of the execution takes place in interpreted code it may be worthwhile to compile it, even though the compilation itself will take a little while. It is also possible to supply native instead of compile, this will compile the script using the native flag, again depending on the characteristics of the escript this could or could not be worth while.

As mentioned earlier, it is possible to have a script which contains precompiled beam code. In a precompiled script, the interpretation of the script header is exactly the same as in a script containing source code. That means that you can make a beam file executable by prepending the file with the lines starting with #! and %%! mentioned above. In a precompiled script, the function main/1 must be exported.

If you're interested in the precompiled option, you may want to check out the build tool rebar, which has an escriptize command for turning all your code into a pre-compiled archive with the appropriate escript header.

For the mechanism of interpreting/compiling used, you can check out the source code to escript. What you'll see is that escript in interpret mode is equivalent (modulo some syntax) to pasting your code into the erl interactive interpreter line by line.

Nathaniel Waisbrot
  • 23,261
  • 7
  • 71
  • 99
  • Thanks for your detail answer! What's the exact representation of codes within the erlang vm? I thought anyway the source files would be converted into bytecodes just like other languages, e.g. python. The compile means bytecode conversion? Then I thought escript must do it before running anyway. – kingluo Jul 01 '15 at 11:27
  • I added a little more detail. I believe Python compiles before running (defaulting to something like escript's `-c` mode). I suspect that on a modern PC or faster, the compilation cost is so small that you'd always want to compile your escripts before running (because most of the time it will cost a few ms and occasionally it will save seconds). – Nathaniel Waisbrot Jul 01 '15 at 12:03