方法 : パフォーマンスを向上させる

更新 : 2007 年 11 月

次の方法でプログラミングすることで、メモリを節約し、デバイス アプリケーションのパフォーマンスを向上させることができます。

Windows フォームおよびグラフィックスで使用されるメモリを節約するには

  • BeginUpdate メソッドおよび EndUpdate メソッドが用意されているコントロール (ComboBoxListBoxListViewToolStripComboBoxTreeView など) では、これらのメソッドを使用します。

  • コントロールの位置を変更するときは、SuspendLayout メソッドおよび ResumeLayout メソッドを使用します。

  • Show() メソッドを使用する前に、バックグラウンドで他のフォームを読み込み、コントロールにデータを設定します。

  • イベント処理コードを制限して必要不可欠なタスクのみを実行し、保留中のプロセスを継続できるようにします。

  • サブスクライバ オブジェクトを破棄する前に、減算代入演算子 (-=) を使用してそのイベントのサブスクリプションを解除します。詳細については、「方法 : イベント サブスクリプションとサブスクリプションの解除 (C# プログラミング ガイド)」を参照してください。サブスクリプションが正しく解除されないと、メモリ リークのような問題が発生する可能性があります。

  • オフスクリーン ビットマップを使用します。カスタマイズ例については、「方法 : イメージをオフスクリーンに描画する」を参照してください。

  • キー イベント ハンドラを追加する代わりに、コントロールの OnKeyDownOnKeyPress、および OnKeyUp の各メソッドをオーバーライドします。

データおよび文字列で使用されるメモリを節約するには

  • for ループでは、オブジェクト変数を使用する代わりに、整数変数 (Int32 または Int64) を使用します。

  • 列挙型の ToString メソッドは、メタデータ テーブルの検索によってパフォーマンスに影響を与えるため、使用を避けます。

  • OutOfMemoryException エラーが発生しないようにします。内部使用または新しいオブジェクト インスタンスのために割り当てるメモリが十分でない場合に、この例外が共通言語ランタイムによってスローされることがあります。この例外を回避するには、64 KB 以上のメモリを消費する大規模メソッドのプログラミングを行わないでください。

  • System.SR.dll を削除します。この DLL には、例外ダイアログ ボックス用のエラー メッセージ文字列が含まれています。このファイルを使用しないでアプリケーションを配置すると、メモリを節約できます。System.SR.dll が存在する場合、.NET Compact Framework は、この DLL に含まれているエラー文字列を動的に読み込みます。

    この DLL ファイルがデバイスに存在しない場合は、すべての例外でメッセージ "リソース アセンブリを読み込めません。" が表示されます。ただし、開発時には、System.SR.dll への参照を Visual Studio プロジェクトに追加して、意味のわかる例外が表示されるようにすると便利です。

  • 文字列は変更できないため、文字列を変更するたびに新しい String オブジェクトが作成されます。頻繁に変更される文字列を構築するときは、StringBuilder の使用を検討してください。

  • DateTime シリアル化で使用される正確な形式がわかっている場合は、DateTimeParseExact メソッドを使用します。それ以外の場合、DateTime パーサーはカルチャ固有の複数の形式を順番に適用することを試みます。

  • 開かれる SqlCeCommand オブジェクトの数を制限し、完了したら破棄します。

ネイティブ コードとの相互運用時にメモリを節約するには

  • プラットフォーム呼び出し操作では、Int32IntPtr などの blittable 型を使用します。この型は、マネージ メモリとアンマネージ メモリの両方で共通の表現が使用されます。32 ビットよりも大きい blittable 値型は、値渡しよりも参照渡しの方が高速で実行されます。blittable 型の詳細については、「.NET Compact Framework の blittable 型」を参照してください。

  • 不要なマーシャリングを減らすために、関数シグネチャの引数で InAttribute 属性および OutAttribute 属性を使用します。

  • PtrToStructurePtrToStringBSTRGetObjectForNativeVariantGetObjectForIUnknown など、IntPtr とマネージ オブジェクト間の手動変換では、Marshal クラスのメソッドを使用します。

  • Prelink メソッドおよび PrelinkAll メソッドを使用して、ネイティブからマネージへの呼び出しをサポートするスタブの JIT コンパイルを実行します。

  • ネイティブ COM オブジェクトが通常は S_FALSE を返し、それ以外では S_OK HRESULT 以外の値を返すようにする場合は、PreserveSig フィールドを true に設定して、マネージ シグネチャがネイティブ シグネチャと一致するようにします。これにより、COM 呼び出しでランタイムが HRESULT 値を例外に変換するときに必要な、try/catch ブロックのオーバーヘッドが回避されます。

  • プラットフォーム呼び出しを複数回行うのではなく、1 回のプラットフォーム呼び出しでできるだけ多くの処理を実行します。

コレクションで使用されるメモリを節約するには

  • コレクションが配列で構成されている場合は、インデクサを使用します。

  • 可能な限り、コレクションのサイズを指定します。これは、動的なサイズ変更によって不要なストレージが大幅に増加することがあるためです。

  • 値型のボックス化およびボックス化解除のオーバーヘッドを回避するために、ジェネリック コレクションを使用します。独自の最適化コレクションを定義すると、最高のパフォーマンスが得られます。

XML で使用されるメモリを節約するには

  • XmlDocument を使用すると、メモリの使用量が増えるので、代わりに XmlTextReader および XmlTextWriter を使用します。

  • パフォーマンスを向上させるには、XmlReaderSettings および XmlWriterSettings の設定を指定します。IgnoreWhitespace プロパティ値および IgnoreComments プロパティ値の設定によってパフォーマンスが劇的に向上することがあります。

  • UTF-8、ASCII、および UTF-16 文字エンコーディングを使用します。これらは ANSI および Windows コードページ エンコーディングよりも高速です。

  • 追加の検証処理を避けるために、解析処理ではスキーマを使用しないようにします。

  • DataSet に XML ソースからデータを設定するときは、列を属性として割り当て、型指定された DataSet を使用します。

  • DataSet にデータを設定するときは、次のアイテムを避けます。

    • スキーマ インターフェイス。

    • 入れ子になったテーブル。

    • 複数の DateTime 列。パフォーマンスを向上させるために、代わりに Ticks プロパティを使用します。

  • XML 逆シリアル化を使用するときは、パフォーマンスを向上させるために、次のガイドラインに従います。

    • 要素名および属性名は、すべての文字を検証する必要があるため、できるだけ短くします。

    • 属性データを基にした XML は、要素データを基にした XML よりも高速です。

    • 可能であれば、XmlNodeReader.Skip メソッドを使用します。

    • パフォーマンスに重大な問題が発生した場合は、バイナリ シリアル化を検討します。

  • メタデータの検索にかかる時間を減らすために、XML シリアル化の型ごとに 1 つの XmlSerializer インスタンスを使用します。

  • 大量の XML をシリアル化するとメモリ不足が発生することがあるため、BinaryReader および BinaryWriter を使用したカスタムのバイナリ シリアル化機構の構築を検討します。

Web サービスの使用時に使用されるメモリを節約するには

  • DataSet の読み取りおよび書き込みを行うときは、DiffGram を使用します。詳細については、「DiffGrams (ADO.NET)」を参照してください。

  • リモート DataSet およびそのスキーマは、XML としてデバイスに保存します。

  • 最初の呼び出しが後続の呼び出しよりも遅いため、スプラッシュ スクリーンが表示されている間に単純な Web サービス メソッドを呼び出します。

  • ネットワーク エラーやデータ エラーを正しく処理するように注意します。

  • DataSet を XML 文字列として手動でシリアル化してから、Web サービス呼び出しを実行すると、パフォーマンスが向上することがあります。

高度なプログラミングで使用されるメモリを節約するには

  • 大規模な操作は非同期で処理します。

  • 仮想呼び出しを避けます。.NET Compact Framework ランタイムの仮想呼び出しは、静的呼び出しまたはインスタンス呼び出しよりも、約 30% 遅くなります。.NET Compact Framework では、制約のあるリソースである vtable を使用しません。そのため、クラスおよびインターフェイス階層を走査してメソッドを呼び出す必要がありますが、これは負荷の高い操作です。.NET Compact Framework では、解決された仮想呼び出しのキャッシュを保持します。そのため、ほとんどの場合、呼び出しを再解釈する必要はありません。

  • できるだけプロパティではなくフィールドを使用します。

  • 値型を定義するときは、GetHashCode メソッドおよび Equals メソッドをオーバーライドします。これらをオーバーライドしないと、ランタイムでは、基本 ValueType クラスのこれらのメソッドの汎用化バージョンが使用されます。

  • リフレクションを使用するかどうかは、慎重に判断します。インスタンス化されていないクラスで調査のためにリフレクションを使用すると、アプリケーションでは、インスタンス化されたオブジェクトのパフォーマンスが影響を受けることがあります。

  • マネージ リソースに完全修飾型名が設定され、RESX ファイル内に正確に記述されていることを確認します。これらは、バージョンが正しく、PublicKeyToken フィールドが存在することが必要です。正しく指定されていない型に対して、最も適切な代替型を見つけるための処理は、パフォーマンスに影響を与えます。

  • 条件によっては、ResourceManager を使用するよりも、アプリケーション データをファイルから直接読み取る方が効率が良く、またそれで十分です。ResourceManager では、リソース バイナリを特定する前に、最も条件にあったサテライト アセンブリを見つけるために、ファイル システム内の複数の場所を調査することがあります。このジョブに適切なツールを使用します。

参照

概念

.NET Compact Framework でのデバイス メモリ管理

.NET Compact Framework に関する「方法」トピック

その他の技術情報

.NET Compact Framework でのパフォーマンスと診断