2015-07-01 4 views
0

Это простой и хорошо известный тестовый скрипт:Почему 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 
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, помогите!

Edit:

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

$ 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). в свой скрипт.

От the documentation:

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

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

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

Для используемого механизма интерпретации/компиляции вы можете проверить the source code to escript. Вы увидите, что escript в режиме interpret эквивалентен (по модулю некоторого синтаксиса) для вставки кода в интерактивный интерпретатор по строкам.

+0

Спасибо за подробный ответ! Каково точное представление кодов внутри erlang vm?Я думал, что исходные файлы будут преобразованы в байт-коды так же, как и другие языки, например. питон. Компиляция означает преобразование байт-кода? Тогда я думал, что escript должен сделать это до запуска в любом случае. – kingluo

+0

Я добавил немного больше деталей. Я считаю, что Python компилируется перед запуском (по умолчанию используется что-то вроде режима esc '-c'). Я подозреваю, что на современном ПК или быстрее стоимость компиляции настолько мала, что вы всегда хотите скомпилировать свои скрипты перед запуском (потому что большую часть времени это будет стоить несколько мс, а иногда это будет экономить секунды). –

+0

Большое спасибо! – kingluo