Erlang соответствие производительности - PullRequest
6 голосов
/ 22 января 2011

новичок в Erlang. Я собираюсь начать писать код. Решение, которое я имею в виду, может пойти одним из двух способов. Я могу сделать кучу математических вычислений, или я могу кодировать это в основном как сопоставление с образцом. Когда я говорю «сопоставление с образцом», я не имею в виду регулярное выражение или что-то подобное - я имею в виду сопоставление с образцом в заголовках предложений.

Производительность обычно не является проблемой, однако в этом приложении это так. Я не спрашиваю вас, какой метод будет быстрее - я уверен, что вы скажете, что не знаете (зависит от многих факторов). То, что я спрашиваю, - это общая производительность сопоставления с образцом Эрланга в заголовках статей. Другими словами, в Prolog движок оптимизирован для выполнения подобных задач, поэтому при прочих равных условиях вам «рекомендуется» разработать решение, которое использует преимущества сопоставления и унификации шаблонов в заголовках предложений.

То же самое относится и к Erlang, т. Е. Оптимизирован ли Erlang для сопоставления с образцом в заголовках предложений, аналогично Prolog? Вместо того, чтобы задавать вопрос здесь, я на самом деле попытался профилировать это на Erlang и написал игрушечную программу для сопоставления шаблонов с заголовками предложений пару миллионов раз против суммирования списка пару миллионов раз. Но система рухнет, если будет настроена на «пару миллионов раз». Но если установить значение менее пары миллионов, результаты вернутся слишком быстро, чтобы я мог что-либо знать о производительности.

Спасибо за любые идеи.

Ответы [ 2 ]

6 голосов
/ 22 января 2011

Как правило, сопоставление с образцом в функциональных языках происходит быстрее или быстрее, чем в Прологе.Я ожидаю, что Эрланг будет работать с коэффициентом 2 по сравнению с Прологом быстрее или медленнее.Поскольку функциональная программа - это не что иное, как сопоставление с образцом, это одна из тех областей, которые вы оптимизируете.

Внутренние компоненты обычно имеют компилятор сопоставления с образцом , который превращает расширенное сопоставление с образцом в более простоесерия проверок с целью минимизации количества проверок.


Хорошо, первая ошибка: " Все, что введено в оболочку, интерпретируется ".Поэтому вместо этого мы компилируем модули:

-module(z).

-compile(export_all).

%% This pattern is highly uninteresting because it only matches
%% on a single value. Any decent system can do this quickly.
cl(0) -> 0;
cl(1) -> 0;
cl(2) -> 0;
cl(3) -> 0;
cl(4) -> 0;
cl(5) -> 0;
cl(6) -> 0;
cl(7) -> 0;
cl(8) -> 0;
cl(9) -> 0.

mcl(L) ->
    [cl(E) || E <- L].

Это дает нам бегун вашего примера.

cl2(a, 0) -> a0;
cl2(a, 1) -> a1;
cl2(a, 2) -> a2;
cl2(b, 0) -> b0;
cl2(b, 1) -> b1;
cl2(b, 2) -> b2;
cl2(c, 0) -> c0;
cl2(c, 1) -> c0;
cl2(c, 2) -> c0.

mcl2(L) ->
    [cl2(A, V) || {A, V} <- L].

Бегун для более интересного примера.Здесь мы можем использовать skips в паттерне.Если (a, 0) не совпадает с a, мы знаем, что можем сразу перейти к случаю (b, 0), поскольку информация об отрицательном совпадении может распространяться как информация в системе.Компилятор сопоставления с образцом обычно выполняет эту оптимизацию.

test1() ->
    L1 = [X rem 10 || X <- lists:seq(1, 2000000)],
    %% A Core 2 Duo 2.4Ghz P8600 eats this in 132984 microseconds without HiPE
    %% c(z).
    %% With HiPE it is 91195 or in 0.6857591890753775 of the time the non-HiPE variant use
    %% c(z, [native, {hipe, [o3]}]).
    timer:tc(z, mcl, [L1]).

Вы должны запустить этот пример самостоятельно и оценить, считаете ли вы, что он достаточно быстр для вашего варианта использования.Обратите внимание, что некоторое время также затрачивается на код отображения и довольно много времени должно быть потрачено на извлечение данных из основной памяти через кэш-память ЦП в ЦП.

test2() ->
    random:seed(erlang:now()),
    L2 = [{case random:uniform(3) of
                   1 -> a;
                   2 -> b;
                   3 -> c
                   end, V rem 3} || V <- lists:seq(1, 2000000)],
    %% With HiPE this is 220937
    %% Without HiPE this is 296980
    timer:tc(z, mcl2, [L2]).

Естественно, этот пример медленнее, так как нам нужно сопоставить больше данных, прежде чем мы получим попадание.Но это более интересный случай, потому что он дает некоторое представление о реальной скорости компилятора соответствия.


Были испробованы параллельные версии, но в этом случае они примерно в 10 раз медленнее, так как накладные расходы на создание 2 миллионов рабочих процессов намного преобладают над фактической обработкой:)

5 голосов
/ 23 января 2011

Это, как сказал @ (NOT VERY) CRAP ОТВЕТ :-), и его пример показывает.

Пролог на самом деле не выполняет сопоставление с шаблоном, которое является однонаправленным, он объединяет что-то вроде двунаправленного сопоставления с логическими переменными.Гораздо проще оптимизировать сопоставление с образцом, а серьезные функциональные языки, такие как Erlang и Haskell, вложили немало работы в оптимизирующий компилятор сопоставления с образцом.Это особенно заметно для глубоких паттернов.

Так что да, Эрланг будет выполнять сопоставление с паттерном быстрее, чем Prolog.

...