web-dev-qa-db-ja.com

C#でアンマネージドセーフコードを使用しないのはなぜですか

C#には、チェックされていないコードを実行するオプションがあります。マネージコードの方がはるかに安全であり、多くの問題を解決するため、通常はそうすることはお勧めしません。

ただし、コードがエラーを引き起こさないことが確実で、メモリの処理方法がわかっている場合、なぜ(高速コードが好きな場合)なぜ一般的なアドバイスに従うのでしょうか。

非常に高速なビットマップ操作を必要とするビデオカメラ用のプログラムを書いたので、これは不思議に思っています。私はいくつかの高速なグラフィカルアルゴリズムを自分で作成し、アンマネージコードを使用してビットマップ上で優れた動作をしました。

一般に、メモリリークやクラッシュのリスクがないことが確かな場合は、アンマネージコードをより頻繁に使用しないのはなぜでしょうか。

PS私の経歴:このプログラミングの世界に少し入って、私は一人で(数年はそうしています)仕事をしています。そのため、このソフトウェア設計の問題がそれほど奇妙ではないことを願っています。先生のように、そんなことを聞​​いてくれる人はあまりいないのです。

10
user613326

まあ、それは主に古くからの格言のケースです

  • 最適化しない
  • (専門家のみ)まだ最適化しないでください

しかし、実際には、安全でないコードを回避する3つの主な理由を考えることができます。

  1. バグ:あなたの質問の重要な部分は「あなたのコードがエラーを引き起こさないことが確かな場合」です。ええと、どうすれば絶対に完全に確信できますか?コードが正しいことを保証する正式な方法で証明者を使用しましたか?プログラミングにおいて確実なことの1つは、バグが発生することです。あなたが安全を脱ぐとき、あなたは新しい種類のバグが谷を這うのを許します。ガベージコレクターにメモリの処理を任せると、多くの問題がなくなります。

  2. あなたが思うほどいつも速いとは限りません:他のポイントは:問題によっては、ゲインがそれほど大きくないかもしれません。今は見つけられないようですが、Java、Scala、Go、C++の速度を比較したGoogleの研究を覚えています。いったん地上に最適化されると、もちろんC++ははるかに高速でした。しかし、「慣用的」な方法でプログラムされたアルゴリズムは、それほど高速ではありませんでした。標準的な構造とイディオム(stlコンテナー、展開されていないループなど)を使用していたという意味でのイディオム。マイクロソフトはC#とC++でも同様の実験を行いました。マイクロソフトのトップエンジニアの1人であるレイモンドチェンは、C#に勝つためにstd :: stringの独自の実装を作成する必要がありました。 (参照: http://www.codinghorror.com/blog/2005/05/on-managed-code-performance-again.html )はるかに少ない労力で、マネージドでかなりまともなパフォーマンスを得ましたコードなので、多くの場合、トラブルに見合う価値はありません。

  3. 再利用性:安全でないコードは、完全信頼環境でのみ使用できます。たとえば、ASP.NETサーバーでは、バッファーオーバーフローによって脆弱性を導入するのは非常に簡単であるため、通常、安全でないコードを使用することはできません。別の例はクリックワンスです。または、アプリケーションがネットワーク共有からアクセスされた場合。そのため、さまざまな展開シナリオでコードを使用することを計画している場合、安全でないコードはゲームの外にあります。

したがって、基本的には、不要なバグが発生する可能性があり、まったく役に立たない可能性があり、コードの再利用性が低下するため、眉をひそめています。

しかし、シナリオが本当にパフォーマンスのためにそれを必要とする場合(そしてそれを証明するためのデータがある場合)、あなたは経験豊富なプログラマーであり、メモリーの処理方法を知っており、コードは制御された環境で使用されます。

27

ある意味で、アンマネージコードは支払い方法の1つです。追加の開発作業で、より高速な実行を購入できます。実際、アンマネージコードは、開発、デバッグ、および保守にさらに多くの時間を必要とします。正確に理解することは、ほとんどの参加者にとって課題です。ある意味で、これはアセンブリでのプログラミングに似ています。確かに、アセンブリで書き込むと、CPUからより多くの電力を引き出すことができます。*、しかしあなたはそのルートに行くより多くの努力を「費やす」。

時々、開発時間の違いは非常に重要です-時間ではなく日。ただし、実行速度の違いはそれほど劇的ではありません。そのため、アンマネージコードの開発は、投稿で説明したような状況(オーディオやビデオの処理など、リソースを大量に消費するアルゴリズムのローカライズされた自己完結型の実装)に似ています。

基本的に、あなたの質問に対する答えは、なぜ誰もがフェラーリを運転しないのと同じです。それははるかに優れた車ですよね? (Un)幸いにも、誰もがそれを買う余裕はありません。


*
4
dasblinkenlight

正確性や数学的な意味でのその他の制約について「確実」である(つまり、証明がある)ことは、命令型言語にとって非常に難しい問題であるためです。多くの場合、プログラムには非常に多くの状態があり、考えられる各状態をチェックしても確認することはできません。そして、建設的な証明の作成は、自動化できるものではありません。

したがって、その理由は、実行を管理することによって提供される保険が、安全でないコードで得られる小さなパフォーマンスの向上を最も重視することが多いためです。もちろん、これは特定のユースケースにも依存します。

0
Tamás Szelei

要するに C++環境でプログラムのすべての作業と管理を妨げるものはありません。あなたはガベージコレクタなしですべてのメモリフープとリークを正しく管理できると確信しているので、C++でそれを行うのは大歓迎です:)

逆に、C#には、.NETフレームワークで安全に実行するための安全で管理された厳密に型指定された開発環境を提供するという利点があります。

アンマネージコードのプログラミングのバックドローの可能性は、開発時間が長くなり、詳細なテストに時間を割り当てることです。もちろん、ソフトウェアがどのように実行されているかについて処理速度が向上し、制御が強化されますになります。

したがって、4.0から始まる.NET Frameworkでアンマネージコードを操作するオプションは、それを使用しないことによる利益をもたらす可能性があることが確実な場合のEdgeケースのオプションです...

0
Yusubov