4

私は、他の人が書いたいくつかの古い Common Lisp コードに基づいて構築しています。これには、いくつかの関数の開始時に次のような行が含まれています。

(declare (ftype (function (&rest float) float) + - * min max))

私の理解では、これの目的は、フォームの最後にリストされている 5 つの関数に float のみが渡されることをコンパイラに伝えることです。コンパイラはこの情報を使用して、より効率的なコードを作成できます。

一部の Lisp はこの宣言について不平を言いません (ABCL、CCL、ECL、LispWorks、CLISP) が、SBCL はデフォルト構成でこの宣言を受け入れません。SBCL は、配置することでそれを受け入れるようにすることができます

(unlock-package 'common-lisp)

.sbclrc 初期化ファイル内。それが私が過去1年ほどやってきたことです。+、- などがそのパッケージに含まれており、コードがこれらの関数の宣言を変更するため、これが必要であると思います。

私の質問は次のとおりです: + や min などの組み込み関数の関数型を宣言すると、SBCL でコンパイルされたコードに有益な効果がありますか? (できるのなら、なぜ SBCL はデフォルトでこれらの宣言について文句を言うのですか?) そのような ftype 宣言を削除してから、unlock-package.sbclrc の行を削除したほうがよいでしょうか?

ありがとう。

4

1 に答える 1

9

私の理解では、これの目的は、フォームの最後にリストされている 5 つの関数に float のみが渡されることをコンパイラに伝えることです。コンパイラはこの情報を使用して、より効率的なコードを作成できます。

また、フロートのみを返します。特定の最適化設定では、Common Lisp コンパイラは実行時チェックを生成せず、float 計算のコードのみを生成する場合があります。また、SBCL は、コードが型宣言に違反していることを検出した場合に、コンパイル時に警告を表示することがあります。

これはエラーの原因でもあります。これ以降 (宣言の範囲内で) のような基本的な関数は、他の数値型 (整数、複素数など) では動作しないように宣言されているためです+-

では、これらの宣言の目的は何ですか? これは移植可能なコードであるため (また、ほとんどの実装ではコンパイル時の型チェックが実装されていません)、最適化のみを目的としています。型推論を使用するため、SBCL では必要ないものもあります。

SBCL がデフォルトで組み込み機能の変更を許可しないのはなぜですか? これは、足を撃たれるのを防ぐためです。基本言語を変更しています。現在、基本的な数値演算はエラーにつながる可能性があります。

それに対処する方法:

  • ローカル宣言のみを使用し、言語をグローバルに変更しないでください。これらはローカルでのみ宣言されていることを示しています-それは良いことです。

  • 代わりに変数の値を宣言する

  • float の場合の特別な関数を記述し、インラインで宣言します。

  • これらのいくつかの関数のコンパイル中にのみ、パッケージ CL のロックを解除してください。後でロックしてください。

私の質問は次のとおりです: + や min などの組み込み関数の関数型を宣言すると、SBCL でコンパイルされたコードに有益な効果がありますか?

逆アセンブルされたコードを見て、プロファイリングすることでも確認できます。適切な最適化設定で関数をコンパイルしていることを確認してください。Common Lisp では、関数DISASSEMBLEはマシンコードを読みやすい方法で表示する必要があります。SBCL コンパイラは、コンパイルされたコードを最適化できないかどうかも通知する必要があります。

于 2013-01-01T10:48:21.687 に答える