17
Micro-ORM
• DataRow => Objectへの変換だけを担うもの
• グラニではDapperを採用
• https://code.google.com/p/dapper-dot-net/
• 文字列で生SQLを書いてにマッピング、それだけ
• 非常に高速
• Dapperだけだとプリミティブすぎるので簡単な上モノは用意しています
• Dapperのシンプルさを損ねないよう、やりすぎないようシンプルに
var dog = connection.Query("select * from dogs where id = @id",
new { id = 100 });
28
同期的シチュエーション
• GetAでRedisやDBアクセスなどがあり10msかかるとする
• 三回アクセスするので、30msかかってる
var a = GetA(); // 10ms
var b = GetB(); // 10ms
var c = GetC(); // 10ms
// +30ms
Slide 29
Slide 29 text
29
非同期的シチュエーション
• GetAAsyncなどで非同期でアクセスがある
• 結果として10msかかるのはかわらない
• 三回アクセスするので、30msかかってる
var a = await GetAAsync(); // 10ms
var b = await GetBAsync(); // 10ms
var c = await GetCAsync(); // 10ms
// +30ms
31
Lazy Revisited
• 昔ながらのLazyなスタイル
• プロパティに初回アクセスあった時に生成
• Pros
• 使うのが簡単
• Cons
• それが遅延なのか分からない
• 何気なく呼んだらDBアクセスが!とか
MyClass myProperty;
public MyClass MyProperty
{
get
{
if (myProperty == null)
{
myProperty = new MyClass();
}
return myProperty;
}
}
Slide 32
Slide 32 text
32
Lazy Revisited
• Lazyなスタイル
• Pros
• Lazyなのが明示的
• Cons
• 使うのが面倒(毎回.Value…)
public Lazy MyProperty { get; private set; }
public Toaru()
{
MyProperty = new Lazy(() => new MyClass());
}
Slide 33
Slide 33 text
33
AsyncLazy
• AwaitableなLazy
• オリジナルはMSのPfxチームから
• http://blogs.msdn.com/b/pfxteam/archive/2011/01/15/101
16210.aspx
• ちょっとだけカスタマイズして使っています
var person = new Person();
var name = await person.Name; // awaitで初期化・取得できる
// 複数同時初期化が可能
await AsyncLazy.WhenAll(person1.Name, person2.Name, person3.Name);
Slide 34
Slide 34 text
34
AsyncLazy + Redis/DB
public AsyncLazy Name { get; set; }
public AsyncLazy Age { get; set; }
public Person()
{
Name = new AsyncLazy(() => Redis.GetString("Name" + id));
Age = new AsyncLazy(() =>
{
using(var dbConn = …) {
return dbConn.Query(“select age from . where id = @id”);
}
}
}
// RedisがパイプラインでNameを同時初期化
await AsyncLazy.WhenAll(person1.Name, person2.Name, person3.Name);
// DBがマルチスレッドでAgeを同時初期化
await AsyncLazy.WhenAll(person1.Age, person2.Age, person3.Age);
Slide 35
Slide 35 text
35
AsyncLazy + Redis/DB
public AsyncLazy Name { get; set; }
public Person()
{
Name = new AsyncLazy(() =>
{
var name = Redis.GetString("Name" + id));
if(name == null)
{
using(var conn = new Connection())
{
name = conn.Query();
}
}
return name;
});
}
// データがあればRedisがパイプラインで、なければDBがマルチスレッドでNameを同時初期化
await AsyncLazy.WhenAll(person1.Name, person2.Name, person3.Name);