更新: 11.6.2016
SICStus Prolog 4.3.2 で観察した不可解なパフォーマンスの不一致は、最近リリースされた SICStus Prolog 4.3.3では完全に解消されました。称賛!
以下の「ランタイム」表を更新して、SICStus Prolog 4.3.3 を含めました。ハイライトは次のとおりです。
(is)/2
以前よりも最大 10 倍高速です。val_of/2
も途方もなく高速になり、ほぼ 2 倍になりました。
MEGO;-)
「プロローグ言語のサイズ手順」という質問に答えると、 SOユーザー@TanosTintinidisは、初心者に導出を紹介する非常に簡単な方法1を提案しました。length/2
[...]また
E
、式を評価しようとしているという理由だけでインスタンス化する必要があることに注意してください。次のように書くことができます。サイズ([], 0)。 size([_|Xs], 1+E) :- size(Xs, E).そして、あなたがそれを呼び出す場合:
?- サイズ([_,_], E)。 E = 1+(1+0)。楽しいですね。
E
最後の、つまり callを評価したい場合があります?- size([1,2], E), N is E
。[...]
楽しい? とても楽しいです! 多くの興味深い実験が待ち構えています。
左寄りの木と右寄りの木
list_siz L ([], 0)。%左利き_ list_sizL([_|Es], N+1) :- list_sizL(Es,N). list_siz R ([], 0)。%右寄り_ list_sizR([_|Es], 1+N) :- list_sizR(Es,N).
組み込み
(is)/2
対val_of/2
val_of(V, E) :- ( E = E1+E2 -> val_of(V1, E1), val_of(V2, E2), V は V1+V2 ; 数(E) -> V = E )。
go(2000000)
さまざまな Prolog プロセッサを使用して実行したランタイムを測定するには2 :
行く(L) :- 長さ(Xs、L)、 member(B_2, [list_sizL,list_sizR]), call(B_2, Xs, E), member(P_2, [is,val_of]), call_time (call(P_2,N,E), T), ( L = N -> writeq(B_2+P_2=T), nl ; throw(up) )。
Intel Core i7-4700MQでは、SICStus と SWI で次のランタイムを観察しました。
| | スイス | SWI | SICStus | SICStus | | | 7.3.20 | 4.3.2 | 4.3.3 | _ -------+--------+---------+---------| list_sizL + (である) | 208 ミリ秒 | 650 ミリ秒 | 60 ミリ秒| 3.4倍 list_sizL + val_of | 381 ミリ秒 | 100 ミリ秒 | 60 ミリ秒 | 6.3倍 -------+--------+---------+---------| list_sizR + (である) | 88 ミリ秒 | 660 ミリ秒 | 70 ミリ秒| 1.2倍 list_sizR + val_of | 346 ミリ秒 | 100 ミリ秒 | 60 ミリ秒 | 5.7倍 -------+--------+---------+---------|
私はこれらの(再現可能な)結果に困惑しています...何が起こっているのか誰か教えてもらえますか?
脚注 1 : 簡潔さと読みやすさのために、変数名はわずかに変更されています。
脚注 2 : 適切なコマンドライン引数を指定して SWI-Prolog 7.3.20 を実行しますswipl -G2G -L2G -O
。