Archive for 8月 2011
非同期処理で UI 改善
Bulding Windows 8 ブログ、日本語化されてたのね。しかも、日本語訳が機械翻訳じゃないっぽい。予算ついてるなぁ、さすがに。
さて、上記エントリーだと、ファイル管理機能の更新点が出てるわけですが。開発者視点で見ると、思いっきり非同期処理で大変そう。数年前から着々とやってきた、非同期 API の整備のたまものですかねぇ。
この手の処理は元々非同期なわけですが、きっと今までは、非同期処理の正しい書き方が面倒、テスト工数的に困難などなどあって、実装をあきらめるなり、不用意に性能落とすようなコードになってたんじゃないかとか考えられるわけです。
非同期処理 API の整備
非同期がらみのここ数年の動きを振り返ってみると、
- 2008~9年:
- Windows Server 2008 R2、Windows 7 の64ビット版に User-Mode Scheduling (UMS) 搭載
- 2010年:
- ネイティブ向けには同時実行ランタイム(Concurrency Runtime、ConcRT)
- .NET 向けにはタスク並列ライブラリ(Task Parallel Library、TPL)
というようなものが。
UMS、ConcRT、TPL
ちなみに、これらはどれも、基本的には、
- むやみに新規スレッドを立てない
- 可能な限りユーザー モードのままで動く
というのを徹底しています。
UMS は、アプリケーションが自身の裁量でスレッドのスケジューリングを行えるようにして、システム スケジューラー(カーネル モードへの移行が必要)の稼働を減らす仕組み。
ConcRT と TPL は、ワーク スティーリング(work-stealing)アルゴリズム(低ロックなキューを使って効率的にタスク実行するしくみ)で、可能な限りスレッド切り替えや、カーネル モード移行をなくして協調的マルチタスクを行うライブラリ。
そして来年
そして、Windows 8 をはじめ、Microsoft 製品で来年くらい出荷のものから、非同期処理による性能や操作性の改善が入っていくのではないかと。バックグラウンド処理するのでフリーズが減ったり、スケジューリングが賢くなってるので大量のジョブを一気にやっても性能落ちなかったり。
なんかこう、OS の基本機能実装 → ライブラリ整備 → UI 層に反映という流れが実に4年くらいかけて行われているわけで。長い道のりよなぁ。
WP7日本発売、Sho 2、等々
やっとこの日が来たなぁ。Windows Phone が正式に日本上陸。しかし、開発ツールがまだ RC という段階での製品発売、結構無茶なレベルで前倒し頑張ったなぁ。
とりあえず、ほんとに売れてるのかそもそも出荷数がかなり絞られてるのかはわかりませんが、店舗・色によっては売り切れも出てるみたいですね。
- Sho がバージョン2になってた
- Sho = (R言語とかと競合するような)データ解析ライブラリとか、IronPython ベースの対話的シェルのセット
- Using Windows Phone As Windows 7 Accelerometer Sensor
- 要約すると「Windows Phone の加速度センサーが Win7 の周辺機器として見えるようなドライバー作ったよ」
読み取り専用
OOP言語でクラスを作る際に重要な点:
- ユーザーには必要最小限の権限しか与えない
- 書き換えが不要なら、読み取り専用に作る
自分で書くか、少なくとも設計段階から関わってる分には別に何も困ることなくやれるんでいいんですが、最近、途中入りのプロジェクトで多少苦労していたり。
例えば、「読み取り専用に作れ」って言われたとき、以下のような書き方が考えられます。
(説明に不要な部分は省略)
using System.Collections.Generic;
class ReadOnlyClass
{
// (クラス外部から)読み取り専用プロパティ
public int X { get; private set; }
// (クラス内部からも)読み取り専用プロパティ
public int Y { get { return _y; } }
private readonly int _y;
// これで読み取り専用のつもりになることが
public int[] ListX { get; private set; }
// 本当は、こう書かないと配列の中身を書き換えられる
public IEnumerable<int> ListY { get { return _listY; } }
private int[] _listY;
}
まあ、何に悩むかというと、3つ目、ListX のところ。本当は ListY の方みたいに、IEnumerable で返さないといけないわけですが。途中入りだと、往々にして ListX みたいな状態になっているわけで。int[] 以外にも、List<int> なことなども。
全部 IEnumerable に書き直したいものの、利用側が foreach (var x in ListX) { } ではなくて、for (int i = 0; i < ListX.Length; ++i) { int x = ListX[i]; } なんですよねぇ、見事に…
ReadOnlyCollection でラップして返すのが楽ではあるものの。1つたりとも、for が必要な箇所がなく(foreach で書ける)。
イテレーターでコルーチン
昔、「[サンプル] イテレータとマイクロスレッド」というような物を書いたわけですが。
Unity のコルーチンがこの仕組みで動いてるらしいというのと、それで、C# のイテレーター構文がよくわからなくて困ってる人がいたので:
サンプル: IteratorCoroutine (ZIP形式、.sln 同梱)