0Pricing
Swift Academy · レッスン

遅延評価と即時評価のトレードオフ

遅延評価が有効な場面と不利になる場面を理解します。

「遅延評価と即時評価のトレードオフ」はCoddyKit上の無料Swift Academyレッスンです。 これはレッスン3/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはSwift Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Swift Academyコースには全4レッスンが含まれています。

万能な近道はありません

遅延評価が常に高速とは限りません。先行するメモリ確保を、アクセスごとのオーバーヘッドと引き換えにし、副作用が実行されるタイミングも変えます。このトレードオフを理解すれば、適切な方法を選べます。

遅延評価が有利な場合:一部だけ利用する

巨大な変換結果の一部だけが必要な場合、遅延評価なら残りをスキップできます —:

let data = Array(1...1_000_000)
let top = data.lazy.map { $0 * 2 }.prefix(3)
print(Array(top))  // [2, 4, 6]  -- 999,997 transforms skipped

先行評価が有利な場合:何度も再利用する

結果を何度も反復する場合、先行評価なら一度だけ計算します。遅延評価では反復するたびに再計算します:

let doubled = [1, 2, 3].map { $0 * 2 }  // computed once
print(doubled.reduce(0, +))  // 12
print(doubled.max()!)        // 6  -- no recompute

遅延評価では再計算されます

同じ遅延ビューでも、反復するたびに処理が再実行されます:

var work = 0
let view = [1, 2, 3].lazy.map { (n: Int) -> Int in work += 1; return n }
_ = view.reduce(0, +)
_ = view.max()
print(work)  // 6  -- transformed twice

要素ごとのオーバーヘッド

遅延評価の各ステップでは、シーケンスを別の型でラップし、要素ごとにクロージャーを呼び出します。小さな配列では、このオーバーヘッドが削減できるメモリ確保のコストを上回ることがあります。

小さな配列なら先行評価で問題ありません

少数の要素をすべて利用する場合は、通常の先行評価を選ぶのが適しています — コードが単純で、メモリ確保のコストもごくわずかだからです:

let nums = [3, 1, 2]
let sorted = nums.map { $0 + 1 }.sorted()
print(sorted)  // [2, 3, 4]

副作用が実行されるタイミングは異なります

遅延評価では、クロージャー本体は定義した行より後で実行されます。遅延変換の中の副作用に依存する処理は避けてください:

var log: [Int] = []
let v = [1, 2].lazy.map { (n: Int) -> Int in log.append(n); return n }
print(log)        // []  -- nothing ran yet
_ = Array(v)
print(log)        // [1, 2]

先行評価を強制する操作

操作によっては、どのみちシーケンス全体を読み取る必要があるため、遅延評価のメリットがありません:

let nums = Array(1...10)
print(nums.lazy.map { $0 * 2 }.sorted())  // sorted must see all -> [2,4,...,20]
print(nums.lazy.map { $0 }.count)         // count walks everything

遅延評価と contains

contains(where:)のように途中で処理を打ち切れる操作は、大きな入力に対して遅延評価の恩恵を受けます:

let big = Array(1...1_000_000)
let found = big.lazy.map { $0 * 2 }.contains { $0 == 8 }
print(found)  // true  -- stops at element 4

判断のチェックリスト

次の場合は遅延評価を使います:元のデータが大きく、必要な一部(prefix / first / contains)だけを残し、1回だけ反復する場合です。次の場合は先行評価を使います:配列が小さい場合、結果を再利用する場合、または細かな最適化より読みやすさを重視する場合です。

let huge = Array(1...100_000)
let first = huge.lazy.filter { $0 % 9973 == 0 }.first
print(first!)  // 9973

推測せずに計測する

パフォーマンスに関する直感は、間違っていることがよくあります。重要な場合は、遅延評価を採用する前に、現実的なデータで両方のバージョンをベンチマークしてください。

let nums = Array(1...50)
let eager = nums.filter { $0 > 25 }.count
let lazyC = nums.lazy.filter { $0 > 25 }.count
print(eager == lazyC)  // true -- same answer, profile for speed

クイックチェック

遅延評価より先行評価を選ぶべきなのは、どのような場合ですか?

まとめ

次のトレードオフを学びました:

  • 大きなデータソースから一部だけを1回の反復で利用する場合は、遅延評価が有利です
  • 小さな配列や結果を再利用する場合は、先行評価が有利です(遅延評価では再計算されます)
  • 遅延変換内の副作用は後で実行されるため、それに依存しないでください
  • 最適化の前に計測してください

次は、カスタム遅延シーケンスの構築です。

よくある質問

「遅延評価と即時評価のトレードオフ」レッスンは無料ですか?

はい。「遅延評価と即時評価のトレードオフ」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Swift Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Swift Academyコースには全4レッスンが含まれています。

「遅延評価と即時評価のトレードオフ」で何を学びますか?

遅延評価が有効な場面と不利になる場面を理解します。 ブラウザで直接実行するハンズオンコードでSwift Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

Swift Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのSwift Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン3/4です。

「遅延評価と即時評価のトレードオフ」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このSwift Academyレッスンでコードを書いて実行できますか?

はい。すべてのSwift Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. lazyプロパティ
  2. 遅延評価のmapとfilter
  3. 遅延評価と即時評価のトレードオフ
  4. カスタム遅延シーケンスの構築
← Swift Academyに戻る