2

SICPでは、関数の使い方を学びました。これは驚くほど便利です。しかし、以下のコードのように、ネストされた関数のコストと混同しています。

(define (sqrt x)
  (define (good-enough? guess)
    (< (abs (- (square guess) x)) 0.001))
  (define (improve guess)
    (average guess (/ x guess)))
  (define (sqrt-iter guess)
     (if (good-enough? guess)
       guess
       (sqrt-iter (improve guess))))
 (sqrt-iter 1.0))

3つの子関数を定義していますが、効率とコストはどうですか? このような関数呼び出しをさらに使用すると?

更新:除数の検索で、以下のコードを見てください

(define (smallest-divisor n)
  (find-divisor n 2))
(define (find-divisor n test-divisor)
  (cond ((> (square test-divisor) n) n)
        ((divides? test-divisor n) test-divisor)
        (else (find-divisor n (+ test-divisor 1)))))
(define (divides? a b)
  (= (remainder b a) 0))

(define (prime? n)
  (= n (smallest-divisor n)))

Q1 :分け目は?明確にするために、最小除数は必要ありません効率とコストはどうですか?Scheme コンパイラはこの状況を最適化しますか。もう少しコンパイラの知識を勉強したほうがいいと思います(͡๏̯͡๏)

q2 : 通訳ではどうですか?

4

4 に答える 4

1

効率の問題は、コンパイラの最適化の問題に分解されます。通常、プロシージャなどのレキシカル プロシージャがあり、 などimproveの自由変数を参照する場合はいつでもx、クロージャを作成する必要があります。クロージャーには、すべての自由変数を格納するために割り当てる必要がある「環境」があります。したがって、スペースのオーバーヘッドと時間のオーバーヘッドがあります (メモリを割り当ててメモリをいっぱいにするため)。

コンパイラの最適化はどこで行われますか? レキシカル プロシージャがレキシカル ブロック (すべてのブロックなど) を「エスケープ」しない場合、コンパイラはプロシージャをインライン化できます。その場合、その環境を含むクロージャーを作成する必要はありません。

しかし、重要なのは、毎日の使用において、字句手続きの使用について心配する必要がないことです。

于 2013-12-11T16:25:04.360 に答える
1

関係ありません。

プログラミング言語を設計する際の重要な側面の 1 つは、多くの場合、一方の効率と他方の表現力のどちらかを選択することです。ほとんどの場合、これら 2 つの側面によって、低水準言語と高水準言語の特性がそれぞれ定義されます。

Scheme は、小さいながらも強力な Lisp 言語ファミリーの高水準言語です。Scheme の最も強力な機能の 1 つは、その表現力と抽象化能力です。Scheme のプログラマとして、ブロック構造は関連する動作をカプセル化し、構造化された方法で問題を解決するため、プロシージャ内でブロック構造を使用しますが、プロシージャの呼び出しやリストの割り当ての実行時コストなど、この動作の低レベルのプロパティは考慮しません。 . これは、Scheme などの高級言語でプログラミングする喜びの一部です。

あなたが言うように: それは驚くほど便利なので、作業を続けて何か素晴らしいものを作成してください。プログラムの動作がかなり遅くなるまで、私はこれらのことを気にせず、プログラムで概念や動作を定義するなどのより難しい問題に集中します。

于 2013-12-11T14:15:14.747 に答える
1

一言で言えば、ごくわずかです。トップレベルで定義された関数の代わりにネストされた関数を使用しても、パフォーマンスに顕著な影響はありません。効率のためではなく、手順を明確にし、より適切に構造化するために、ネストされた関数 ( SICPの用語では「ブロック構造」) を使用します。

ブロック構造と呼ばれるこのような定義の入れ子は、基本的に最も単純な名前のパッケージングの問題に対する適切な解決策です。

関数が定義された場所によって、関数のルックアップにかかる時間にわずかな違いがあるかもしれませんが、それはインタープリターの実装の詳細に依存しますそれについて心配する価値はありません。

于 2013-12-11T13:42:54.187 に答える