環境:
SQL CE
Windows Phone 7.5 以降
Visual Studio 2012 update 3
サンプル:全タスク 30 件、今日のタスク 10 件、明日のタスク 10 件、期限切れのタスク 10 件
要件:
To Do アプリで、ホームページに 3 つの数字、すべてのタスク、今日のタスク、明日のタスクを表示する必要があります。
元のコード:
private Stopwatch sw=new Stopwatch();
using (TasksDataContext db = new TasksDataContext(TasksDataContext.DBConnectionString))
{
sw.Start();
var allTask = db.TasksItems.Where(t => t.Title != null && t.IsCompleted != true);
System.Diagnostics.Debug.WriteLine( "allTask:"+sw.ElapsedMilliseconds.ToString());
Taskamount = allTask.Count();
var todayTask = db.TasksItems.Where(t => t.DueDate != null & t.DueDate.Value.Date == DateTime.Now.Date & t.IsCompleted == false);
System.Diagnostics.Debug.WriteLine("todayTask:" + sw.ElapsedMilliseconds.ToString());
todayNumber = todayTask.Count();
var tomorrowTask = db.TasksItems.Where(t => t.DueDate != null & t.DueDate.Value.Date == DateTime.Now.Date.AddDays(1) & t.IsCompleted == false);
System.Diagnostics.Debug.WriteLine("tomorrowTask:" + sw.ElapsedMilliseconds.ToString());
sw.Stop();
tomorrowNumber = tomorrowTask.Count();
}
遅刻コード:
private Stopwatch sw=new Stopwatch();
using (TasksDataContext db = new TasksDataContext(TasksDataContext.DBConnectionString))
{
sw.Start();
var allTask = db.TasksItems.Where(t => t.Title != null && t.IsCompleted != true);
System.Diagnostics.Debug.WriteLine( "allTask:"+sw.ElapsedMilliseconds.ToString());
Taskamount = allTask.Count();
var todayTask = allTask.Where(t => t.DueDate != null & t.DueDate.Value.Date == DateTime.Now.Date & t.IsCompleted == false);
System.Diagnostics.Debug.WriteLine("todayTask:" + sw.ElapsedMilliseconds.ToString());
todayNumber = todayTask.Count();
var tomorrowTask = allTask.Where(t => t.DueDate != null & t.DueDate.Value.Date == DateTime.Now.Date.AddDays(1) & t.IsCompleted == false);
System.Diagnostics.Debug.WriteLine("tomorrowTask:" + sw.ElapsedMilliseconds.ToString());
sw.Stop();
tomorrowNumber = tomorrowTask.Count();
}
debug output
original:
1回目:
allTask:9
todayTask:165 TomorrowTask
:221
2回目:
allTask:10
今日Task:179
明日Task:233
3回目:
allTask:14
今日Task:168
明日Task:225
4回目:
allTask:8
今日Task:181
明日Task:236
5 回目:
allTask:8
今日Task:166
明日Task:221
最新:
1 回目:
allTask:9
今日Task:157
明日Task:216
2回目:
allTask:8
今日Task:163
明日Task:219
3回目:
allTask:8
今日Task:161
明日Task:216
4回目:
allTask:8
今日Task:164
明日Task:222
5回目:
allTask:9
今日Task:153
明日Task:210
コードを変更する理由:
今日のタスクと明日のタスクはすべてのタスクのサブセットであるためです。linq クエリ変数を再利用すると、パフォーマンスが向上すると思います。結果はわずかなブーストを示しています。
私を混乱させるもの:
MSDNのlinqセクションを読んだところ、次のように書かれていました:
LINQ では、クエリの実行はクエリ自体とは異なります。つまり、クエリ変数を作成しただけではデータを取得していません。
MSDN の発言によると、linq クエリを再利用してもパフォーマンスは向上しませんが、パフォーマンスが低下します。
コンパイラが次のコードを実行すると:
var todayTask = allTask.Where(t => t.DueDate != null & t.DueDate.Value.Date == DateTime.Now.Date & t.IsCompleted == false);
2 つの操作を行います。1 つは allTask 用で、もう 1 つは todayTask 用です。しかし、「db.taskitems.Where()」を使用すると、単一の操作しか実行されません。
私の質問
1.なぜ速いのですか? (コンパイラはコンパイル時にコードを最適化しますか?)
2. 速度を上げるためのより良い方法はありますか?