4

私はCommonLispの初心者なので、Common Lisp(SBCL )を使用してSPOJの問題を解決しようとしました。最初の問題は、42番が見つかるまで数字を読み取るという単純な作業です。これが私の解決策です:

(defun study-num ()
  (let ((num (parse-integer (read-line t))))
    (when (not (= num 42))
      (format t "~A~%" num)
      (study-num))))
(study-num)

解決策は受け入れられます。しかし、結果の詳細を調べたところ、57MのMEMが使用されていることがわかりました。血まみれの無理ですが、理由がわかりません。最適化するにはどうすればよいですか?

4

3 に答える 3

5

末尾呼び出しの除去を有効にするために十分な最適化をオンにせずに、再帰呼び出しを繰り返し行っています(SBCLはこれを行いますが、「速度の最適化」を高く設定し、「デバッグ情報の最適化」を低く設定した場合に限ります)。

Common Lisp標準は、実装品質の問題として末尾呼び出しの除去を残し、他のループ構造(LOOPやDOなど、どちらもこのアプリケーションに適している可能性があります)を提供します。

さらに、新しく起動したSBCLは、ランタイム環境とベースイメージを取り込む必要があるため、予想よりも大きくなる可能性があります。

于 2012-01-25T12:46:54.417 に答える
4

Common Lispが、最初のプロンプトを表示するためだけにRAMにロードされた完全なライブラリとコンパイラを備えたオンライン言語環境であることを認識していないと思います。その後、プログラムのロードは、おそらく目立ったサイズの増加でさえほとんどありません。Lispは、コードとコードから到達可能なlibルーチンのみで構成される独立した実行可能ファイルをコンパイルおよびリンクしません。それがCや同様の言語が行うことです。代わりに、Lispはコードをすでにかなりの規模のオンライン環境に追加します。新しいユーザーとして、それはひどい継ぎ目です。しかし、100 MBのRAMを搭載した最新の汎用コンピューターを使用している場合は、オンライン環境のメリットを享受しているため、すぐに忘れてしまうものになります。Thinsは「動的言語環境」とも呼ばれます。

于 2014-02-09T22:28:02.193 に答える
4

さまざまなLisp実装には、プログラムを作成するためのさまざまな方法があります。1つは、Lispシステムのメモリのイメージをダンプし、それをディスクに書き込むことです。再起動時に、このイメージはランタイムとともにロードされ、再起動されます。これは非常に一般的です。

これは、実行可能ファイルを保存するときにSBCLが行うことでもあります。したがって、この実行可能ファイルには完全なSBCLが含まれています。

他のいくつかの実装は、イメージ(CLISP)を使用して小さな実行可能ファイルを作成し、いくつかは実行可能ファイル(Allegro CL、LispWorks)から未使用のコードを削除でき、他の実装はC(mocl)へのコンパイルを介して非常に小さなプログラムを作成します。

SBCLには、実行可能ファイルのサイズを縮小する簡単な方法が1つだけあります。それは、イメージを圧縮できることです。

于 2015-01-22T09:19:09.003 に答える