Performance Erlang模式匹配性能

Performance Erlang模式匹配性能,performance,erlang,pattern-matching,Performance,Erlang,Pattern Matching,新到二郎。我正要开始写一些代码。我想到的解决办法可以有两种。我可以做一系列的数学计算,或者我可以将其编码为模式匹配。当我说“模式匹配”时,我不是指正则表达式或类似的东西——我指的是子句头中的模式匹配 性能通常不是一个问题,但是在这个应用程序中它是一个问题。我不是问你哪种方法更快——我肯定你会说你不知道(取决于许多因素)。我要问的是子句头中Erlang模式匹配的一般性能。换句话说,在Prolog中,引擎经过优化以完成这类工作,因此在所有其他条件相同的情况下,“鼓励”您设计一个利用子句头中的模式匹配

新到二郎。我正要开始写一些代码。我想到的解决办法可以有两种。我可以做一系列的数学计算,或者我可以将其编码为模式匹配。当我说“模式匹配”时,我不是指正则表达式或类似的东西——我指的是子句头中的模式匹配

性能通常不是一个问题,但是在这个应用程序中它是一个问题。我不是问你哪种方法更快——我肯定你会说你不知道(取决于许多因素)。我要问的是子句头中Erlang模式匹配的一般性能。换句话说,在Prolog中,引擎经过优化以完成这类工作,因此在所有其他条件相同的情况下,“鼓励”您设计一个利用子句头中的模式匹配和统一的解决方案

Erlang是否也是如此,即Erlang是否针对子句头中的模式匹配进行了优化,类似于Prolog?我没有在这里问这个问题,而是尝试在Erlang中对此进行分析,并编写了一个玩具程序,对子句头进行几百万次模式匹配,而对列表进行几百万次求和。但是如果设置为“几百万次”,系统就会崩溃。但是如果设置为少于几百万次,结果会很快恢复,我对性能一无所知


感谢您的见解。

一般来说,函数式语言中的模式匹配与Prolog中的模式匹配一样快。我希望Erlang的性能比Prolog高2倍,更快或更慢。由于功能程序几乎只不过是模式匹配,所以它是您经常优化的领域之一

内部通常有一个模式匹配编译器,它将高级模式匹配转换为一系列更简单的检查,目的是最小化检查的数量


好的,第一个问题是:“shell中引入的任何内容都会被解释”。因此,我们编译模块:

-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].
您必须自己运行这个示例,并评估它是否足够快,适合您的用例。请注意,映射代码中也花费了一些时间,并且必须花费相当多的时间通过CPU缓存将数据从主存拉到CPU上

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]).
test2()->
随机:种子(erlang:now()),
L2=[{大小写随机:一致的(3)
1->a;
2->b;
3->c
最后,V rem 3}| | V这基本上就像@(不是很)垃圾答案:-)所说的那样,他的例子显示了这一点

Prolog并没有真正做单向的模式匹配,它做的是统一,有点像逻辑变量的双向模式匹配。它更容易优化模式匹配,像Erlang和Haskell这样的严肃函数语言在优化模式匹配编译器中投入了大量的工作深纹图案尤其引人注目


因此,是的,Erlang将比Prolog更快地进行模式匹配。

发布Codz。重新措辞,作为一个关于为什么会崩溃的问题。代码是2个非常简单的程序。第一个程序是序列子句(0)->0;子句(1)->0;(最多10个)的10个子句头为了进行测试,我使用duplicate创建了一个包含200万个0的列表,并使用map To map子句将其映射到该列表上。第二个程序只是简单地使用duplicate创建了包含7个整数的200万个列表,然后使用map将求和映射到该列表上。我再次尝试测试作为编程技术使用的模式匹配的相对性能。我的问题是鼓励Erlang程序员使用模式匹配(如果可行)正如Prolog程序员一样。切换到静态类型检查语言(如Haskell)会消除OP的所有顾虑吗?尽管我很欣赏你的评论……不,我不会切换到静态类型语言:-)静态语言通常有更快的模式匹配,因为它们有更多的信息可以利用到类型规范将模式匹配与可能到达的数据进行序列化。然而,在Erlang中使用HiPE编译会返回一些数据。出色的分析-是的,这正是我试图做的实验。
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]).