BT

.NETが不変になる

| 作者: Jonathan Allen フォローする 594 人のフォロワー , 翻訳者 大田 緑 - (株)チェンジビジョン フォローする 1 人のフォロワー 投稿日 2013年1月17日. 推定読書時間: 3 分 |

原文(投稿日:2013/01/05)へのリンク

 

.NETの開発でよく誤解されるのは、IEnumerable型やReadOnlyCollection型の変数がスレッドセーフだという考え方だ。MicrosoftのAndrew Arnott氏は次のように説明している。

ReadOnlyCollection<T>やIReadOnlyList<T>、IEnumerable<T>を渡された時、唯一保証されるのは自分でデータを変更できないことです。コレクションを渡した人が、データを変更しないことを保証するものではありません。それでも、データが変わらないという確信を持たなければならない時もあるでしょう。これらの型は、内容の変更を通知するイベントを提供していませんし、変更するとしても、ひょっとしたらその内容を列挙している間に別のスレッドで実行されるかもしれません。このようなふるまいは、アプリケーション内でデータの破損やランダムな例外につながる可能性があります。

IEnumerableやReadOnlyCollectionを使いたくなるようなシナリオで、真にスレッドセーフなコレクションを提供するために、MicrosoftのBase Class Library (BCL) チームは、新しい不変コレクションのプレビューを提供している。関数型プログラミング言語で見つけられた技術に基づいて、普通はコレクションを変化させるメソッドが、その代わりに新しいコレクションを作り出す。データ共有は、古いコレクションと新しいコレクションの間で可能になり、効率的になる。

不変コレクションの興味深い特徴は、パブリックコンストラクタを持たないことだ。代わりに、作業は、常にImmutableXxx<T>.Emptyで始まる。Andrew氏は次のように述べている。

スタティックなEmptyプロパティを使うことは、よく確立したパターンを抜け出すことであり、それには理由があります。コンストラクタは、オブジェクトを割り当てなければなりません。これらのコレクションを不変にするには、新しいオブジェクトを空のリストにしなければなりません。コレクションを変更すると新しいコレクションができ、コンストラクタを使うと空のリストを表す複数のオブジェクトを作り出すことになります。これは無駄なことです。スタティックなプロパティを使えば、アプリ内のすべてのコードで共有できる空のリストであるシングルトンを返せるようになります。

ビルダとコレクション

不変コレクションの構築は、メモリの割り当てのために非常にコストがかかる。同様のことは、charの不変コレクションであるstringでも起こっている。これを解決するために、不変コレクションはToBuilderメソッドを公開するだろう。これにより、コストをかけずに修正できるビルダオブジェクトを返す。その後は、不変コレクションを再取得するToImmutable を使えばよい。

パフォーマンス

不変コレクションのパフォーマンスは、少々扱いにくい。以下のチャートから分かるように、不変コレクションの順番は、実際にはかなりよい。そして、首尾一貫している。コレクションの内部配列の最大サイズを超えるとコレクションを完全にコピーしなければならなくなるが、そのことは心配しなくてよい。普通のコレクションとは異なり、不変コレクションはアイテムが削除されると、未使用スペースを実際には開放するだろう。



しかし、そこにはコストが発生する。操作毎に、メモリ内に他のオブジェクトを割り当てなければならず、そのためにガベージコレクタを精一杯使うことになる。最大の勝利は、コレクションのスナップショットのコピーを作るときだ。しかし、最後にお勧めするのは、「役割を果たす簡単なコードを使い、必要があれば、パフォーマンスチューニングをする」ことだ。

このプレビューは、Microsoft.Bcl.Immutable NuGet packageで参照できる。

 

この記事に星をつける

おすすめ度
スタイル

こんにちは

コメントするには InfoQアカウントの登録 または が必要です。InfoQ に登録するとさまざまなことができます。

アカウント登録をしてInfoQをお楽しみください。

あなたの意見をお聞かせください。

HTML: a,b,br,blockquote,i,li,pre,u,ul,p

このスレッドのメッセージについてEmailでリプライする
コミュニティコメント

HTML: a,b,br,blockquote,i,li,pre,u,ul,p

このスレッドのメッセージについてEmailでリプライする

HTML: a,b,br,blockquote,i,li,pre,u,ul,p

このスレッドのメッセージについてEmailでリプライする

ディスカッション

InfoQにログインし新機能を利用する


パスワードを忘れた方はこちらへ

Follow

お気に入りのトピックや著者をフォローする

業界やサイト内で一番重要な見出しを閲覧する

Like

より多いシグナル、より少ないノイズ

お気に入りのトピックと著者を選択して自分のフィードを作る

Notifications

最新情報をすぐ手に入れるようにしよう

通知設定をして、お気に入りコンテンツを見逃さないようにしよう!

BT