Почему escript выводит другой результат?

Это простой и известный тестовый скрипт:

-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? Я новичок в Эрланге, пожалуйста, помогите!

Редактировать:

Когда escript запускает файл луча, он выводит тот же результат, что и erl:

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

Что просходит? Я знаю, что *.beam - это скомпилированные коды, но escript не компилирует скрипт перед его запуском? Я все еще в замешательстве.

1 ответ

Решение

Разница в том, что ваш второй прогон интерпретируется, а ваш первый прогон был скомпилирован. Бежать

escript -c processes.erl

и вы получите время, которое в основном то же самое. Вы также можете получить это поведение, поместив директиву -mode(compile). в вашем сценарии.

Из документации:

Выполнение интерпретированного кода медленнее, чем скомпилированный код. Если большая часть выполнения выполняется в интерпретируемом коде, возможно, стоит скомпилировать его, даже если сама компиляция займет некоторое время. Также возможно предоставить native вместо compile, это скомпилирует скрипт, используя собственный флаг, опять же, в зависимости от характеристик escript, это может или не может стоить того.

Как упоминалось ранее, возможно иметь скрипт, который содержит предварительно скомпилированный код луча. В предварительно скомпилированном сценарии интерпретация заголовка сценария точно такая же, как в сценарии, содержащем исходный код. Это означает, что вы можете сделать исполняемый файл луча, добавив в файл строки, начинающиеся с #! а также %%! упомянутое выше. В предварительно скомпилированном скрипте функция main/1 должна быть экспортирована.

Если вы заинтересованы в предварительно скомпилированном параметре, вы можете проверить панель инструментов сборки, которая имеет escriptize Команда для превращения всего вашего кода в предварительно скомпилированный архив с соответствующим заголовком escript.

Что касается используемого механизма интерпретации / компиляции, вы можете проверить исходный код в escript. То, что вы увидите, это сценарий в interpret Режим эквивалентен (по модулю некоторый синтаксис) вставке вашего кода в erl интерактивный переводчик построчно.

Другие вопросы по тегам