多くの開発者と同様に、私はかなりの時間Rustに興味がありました。 ハッカーニュースの多くの見出しに表示されるだけでなく、言語が安全性とパフォーマンスに取る斬新なアプローチのためだけでなく、人々が愛と賞賛の特定の感覚でそれについて話しているように見えるからです。 それに加えて、Rustは私のお気に入りのgo-to言語であるSwiftと同じ目標と機能を共有しているので、私にとって特に興味があります。 私は最近、いくつかの小さな個人的なプロジェクトでRustを試してみる時間を取ったので、特にSwiftとの比較方法で、言語の印象を文書化するのに少し時間

全体像

RustとSwiftには多くの共通点があります:これらは両方とも、強力で現代的な型システムと安全性に焦点を当てたコンパイルされた言語で 代数型やオプション値のファーストクラス処理などの機能は、これらの言語の両方で、多くのクラスのエラーを実行時からコンパイル時に移動するのに役立ちます。

だから、これらの言語はどのように違うのですか? 私が違いを特徴付けることができる最良の方法は次のとおりです:

Swiftは安全なコードを簡単に書くことができます。
Rustは安全でないコードを書くのを困難にします。

これら二つの声明は同等に聞こえるかもしれませんが、重要な区別があります。 どちらの言語も安全性を達成するためのツールを持っていますが、それを達成するためには異なるトレードオフがあります。Swiftはパフォーマンスを犠牲にして人間工学を優先し、Rustは人間工学を犠牲にしてパフォーマンスを優先します。

トレードオフ: パフォーマンスと人間工学

この優先度の違いが実証される最大の方法は、これらの言語がメモリ管理に持っているアプローチにあります。 メモリ管理に対する言語のアプローチは、Rustのユニークなセールスポイントの一つであるため、私はRustから始めます。

Rustでは、メモリは主に静的に管理されます(はい、参照カウントのようなメモリ管理の他のモードがありますが、今のところそれらは無視します)。 これが意味することは、Rustコンパイラがプログラムを分析し、一連のルールに従って、いつメモリを割り当てて解放するかを決定することです。

Rustは安全を提供するために、ボローチェックと呼ばれる新しい戦略を使用しています。 これが実際に機能する方法は、プログラマとして、変数(つまり、メモリ位置への参照)を渡すたびに、参照が可変であるか不変であるかを指定する必 次に、コンパイラは一連のルールを使用して、1つのメモリを2つの場所で一度に変更できないようにし、プログラムにデータ競合がないことを証明し

このアプローチは、メモリ使用量とパフォーマンスに関していくつかの非常に有益な特性を持っています。 借用チェックは、一般的に値のコピーを回避するため、メモリでは非常に節約できます。 また、作業は実行時ではなくコンパイル時に行われるため、ガベージコレクションのようなソリューションのパフォーマンスオーバーヘッ

しかし、使いやすさに関してはいくつかの欠点があります。 Rustの所有権の性質上、Rustでは機能しないデザインパターンがいくつかあります。 たとえば、二重にリンクされたリストやグローバル変数のようなものを実装するのは簡単ではありません。 これは時間とともにより直感的になり、これらの問題に対する回避策がありますが、Rustは他の言語にはないプログラマに制限を課しています。

Rustほど頻繁に語られることはありませんが、Swiftはメモリ管理に関しても興味深い話をしています。

Swiftには、参照型と値型の二つの基本的な型の変数があります。 一般に、参照型はヒープ割り当てされ、参照カウントによって管理されます。 つまり、実行時に、参照カウントされたオブジェクトへの参照の数が追跡され、カウントがゼロに達するとオブジェクトの割り当てが解除されます。 これは、参照カウントが変更されるたびに、すべてのCPUスレッド間で同期が必要であることを意味します。 これには、マルチスレッドアプリケーションで参照が誤って解放される可能性を排除するという利点がありますが、CPU同期が非常に高価であるため、

Rustには参照カウントと原子参照カウントのためのツールもありますが、これらはデフォルトではなくオプトインです。対照的に、

値型は一般的にスタック割り当てられ、そのメモリは静的に管理されます。 しかし、Swiftの値型の動作は、Rustがメモリをどのように扱うかとは大きく異なります。 つまり、値型が新しい変数に書き込まれるたびに、または関数に渡されるたびに、コピーが作成されます。

デフォルトでコピーオンライトコピーは、借用チェックの同じ目標のいくつかを達成します:プログラマとして、一般的に、プログラムの他の場所で予期しない副作用のために値が不思議に変化することを心配する必要はありません。 また、Swiftには単に存在しないrustには所有権関連のコンパイル時エラーのクラス全体があるため、借用チェックよりも少し少ない認知負荷を必要とします。 これらの追加のコピーは、完了するために追加のメモリ使用量とCPUサイクルを必要とします。

Rustでは、借用チェックエラーを沈黙させる方法として値をコピーすることもできますが、コピーを明示的に指定する必要があるため、これは視覚的なノイ

だから、ここでは、これら二つの言語によって行われたトレードオフの良い例を持っています:Swiftは、まだ安全性のレベルを維持しながら、メモリを管理す これは、C++プログラマが最適化に多くの考えを与える前に、ベストプラクティスに従ってメモリを処理する方法に少し似ています。 これにより、低レベルの詳細をあまり考慮せずにコードをジャンプして書くことが非常に簡単になり、PythonやGolangのような言語では得られない基本的なラン しかし、それはあなたのプログラムを実行するまで、それを実現することなく落ちるのは簡単ですいくつかのパフォーマンスの崖が付属しています。 高性能なSwiftコードを書くことは可能ですが、これを達成するためには慎重なプロファイリングと最適化が必要なことがよくあります。一方、Rustは、メモリの管理方法を指定するための多くの特定のツールを提供し、安全でない動作を避けるためにそれらを使用する方法にいくつかの厳しい制 これにより、すぐにすぐに非常に優れたパフォーマンス特性が得られますが、すべてのルールに従うことを保証するための追加の認知オーバーヘッドを取

これらの言語はいくつかの共通の目標を持っていますが、異なるユースケースに役立つ根本的に異なる特性を持っているということです。 たとえば、Rustは、メモリとCPUサイクルの最適な使用が非常に重要であり、code-compile-runループが遅くなる可能性がある組み込み開発のような明確な選択のよう Swiftは、パフォーマンスが二次的な懸念であるデータサイエンスやサーバーレスロジックのようなものにとってはより良い選択かもしれませんが、低レベルの詳細を多く考慮することなく、問題のドメインに近い作業をすることは価値があります。

いずれにしても、私は将来これらの言語の両方に従うことに非常に興味があり、私はSwiftとRustの比較についてのより多くの観察とともにこの投稿に従

コメントを残す

メールアドレスが公開されることはありません。