5

我来自 Prolog 背景。Prolog 通常在谓词的第一个参数上建立索引(大多数体面的系统允许你改变它,索引多个参数等)。无论如何,了解引擎索引子句的方式可以让您安排参数和谓词以获得更好的性能。

我最近一直在用 Erlang 编码,但还没有看到任何关于它如何索引子句标题以及我应该如何安排参数和子句的信息。有人知道吗?

谢谢。

4

1 回答 1

12

Erlang 索引所有参数,从左到右,到任何深度和所有类型。我们使用的基本算法在 Simon Peyton Jones的函数式编程语言的实现中进行了描述并取自,我对其进行了修改以适应 Erlang 处理类型的方式。这是一本好书,即使它现在有点老了,对我来说是一次真正的 AHA 体验。

这意味着实际上不需要重新排序参数来尝试优化模式匹配,至少不是为了速度。保持一致和清晰要好得多,这就是的做法,是否有一种惯用的方式来在 Erlang 中对函数参数进行排序?. 这意味着以下代码没有问题:

foo(X, [{a,A}|Rest], ...) -> ... ;
foo(X, [{b,B}|Rest], ...) -> ... ;
foo(X, [{c,C}|Rest], ...) -> ... ;
foo(X, [{d,D}|Rest], ...) -> ... ;
...

永远不需要通过将其分解为嵌套case表达式来尝试“帮助”编译器,通常情况会更糟。这样做的唯一原因是它使代码更清晰地显示了您的意图。

如果您确实想尝试优化模式匹配,请尝试重新排序子句,以便所有出现文字的情况都聚集在一起。例如:

foo(1, ...) -> ... ;
foo(2, ...) -> ... ;
foo(7, ...) -> ... ;
foo(8, ...) -> ... ;
foo(I, ...) when is_integer(I), I >= 3, I =< 6 ->
    ... .

好于

foo(1, ...) -> ... ;
foo(2, ...) -> ... ;
foo(I, ...) when is_integer(I), I >= 3, I =< 6 ->
    ... ;
foo(7, ...) -> ... ;
foo(8, ...) -> ... .

索引会更好,但同样不要过度,因为差异不是很大,保持清晰。这在任何深度也有效,例如在列表中元组的第一个元素的第一个代码示例中。

其中大部分是函数式语言的标准。

于 2011-02-07T14:36:58.940 回答