public class GoodsDatabase : DbManager
{
public Table<Good> Good { get { return GetTable<Good>(); } }
}
[TableName("goods")]
public abstract class Good : EditableObject<Good>
{
[Identity, PrimaryKey]
public abstract int GID { get; set; }
[MapField("title")]
public abstract String Title { get; set; }
}
Пытаюсь линком выбрать записи:
using (var db = new GoodsDatabase())
{
var sw = new Stopwatch();
sw.Start();
db.SetCommand("SELECT title FROM goods WHERE GID != 1");
var list = db.ExecuteScalarList<String>();
sw.Stop();
Console.WriteLine("Time 1: " + sw.ElapsedMilliseconds);
sw.Reset();
sw.Start();
var goods = db.Good.Where(el => el.GID != 1).ToList();
sw.Stop();
Console.WriteLine("Time 2 : " + sw.ElapsedMilliseconds);
Console.ReadKey();
}
Получаю вывод:
Time 1: 197
Time 2: 5071
Запускал десятки раз в debug/release — время LINQа всегда около 5 секунд.
Почему так и как сделать, что бы было быстро?
Здравствуйте, iGrog, Вы писали:
G>Запускал десятки раз в debug/release — время LINQа всегда около 5 секунд. G>Почему так и как сделать, что бы было быстро?
Я так понимаю запускал десятки раз процесс с этими двумя запросами?
Если так, то холодный старт требует времени. Второй запрос будет быстр. Попробуй завернуть в цикл и посмотреть.
Здравствуйте, fddima, Вы писали:
F>Здравствуйте, iGrog, Вы писали:
G>>Запускал десятки раз в debug/release — время LINQа всегда около 5 секунд. G>>Почему так и как сделать, что бы было быстро? F> Я так понимаю запускал десятки раз процесс с этими двумя запросами?
Да.
F> Если так, то холодный старт требует времени. F> Второй запрос будет быстр. Попробуй завернуть в цикл и посмотреть.
Да в цикле выполняются быстро.
А как "подготовить" BLToolkit, что сейчас начнутся запросы?
Можно как-то в фоне это сделать? Ибо при клике на UI-кнопочку тормоза в 5 секунд — это не подходит... Даже если это впервый раз.
Здравствуйте, iGrog, Вы писали:
G>Да в цикле выполняются быстро. G>А как "подготовить" BLToolkit, что сейчас начнутся запросы?
Тут надо понять сразу что именно сильно "тормозит".
1-ый кандидат — это джиттинг (компиляция) IL. Здесь стандартные способы борьбы (навроде NGen). При том не обязательно тут виновен только BLT, всё что он дёргает "первый" раз тоже загружается, инициализируется.
2-ой — динамическая генерация аксессоров для классов. Здесь в помощь BLTGen. На сайте BLT есть кое-что по этому поводу..
G>Можно как-то в фоне это сделать? Ибо при клике на UI-кнопочку тормоза в 5 секунд — это не подходит... Даже если это впервый раз.
Это ближе к 3-ей технике, и тут ты и сам уже отвечаешь на свой вопрос. Warm-up.
Да, можно в фоне выполнить запрос, который в итоге заставит выполнить оту самую подкапотную работу, которая мешает. Но это хорошо подходит, для случая когда есть время выполнить это самое что-то в фоне. Я в одном из проектов использовал именно этот вариант (только не применительно к BLT), только у меня сервис, и он естественным образом по логике работы при старте должен был выполнить некоторые действия, так что плюшки получил бесплатно.
По первым двум способам — лично не делал, не было необходимости.
Здравствуйте, fddima, Вы писали:
F>Здравствуйте, iGrog, Вы писали:
G>>Да в цикле выполняются быстро. G>>А как "подготовить" BLToolkit, что сейчас начнутся запросы? F> Тут надо понять сразу что именно сильно "тормозит".
Как это можно узнать точно?
F> 1-ый кандидат — это джиттинг (компиляция) IL. Здесь стандартные способы борьбы (навроде NGen). При том не обязательно тут виновен только BLT, всё что он дёргает "первый" раз тоже загружается, инициализируется. F> 2-ой — динамическая генерация аксессоров для классов. Здесь в помощь BLTGen. На сайте BLT есть кое-что по этому поводу..
Не понял этого шага с BLTGen.
Подписал сборку Infrastructure, где находятся классы GoodsDatabase и Good.
В PostBuild сделал как и написано.
После билда в сборке /bin/Debug появился файлик Infrastructure.BLToolkitExtension.dll
В Program.cs (консольное приложение — другой проект) написал:
TypeFactory.LoadTypes = true;
using(var db = new GoodsDatabase())
{
...
}
Здравствуйте, fddima, Вы писали:
F>Здравствуйте, iGrog, Вы писали:
F>>> Тут надо понять сразу что именно сильно "тормозит". G>>Как это можно узнать точно? F> Пробовать.
Здравствуйте, iGrog, Вы писали:
G>Здравствуйте, fddima, Вы писали:
F>>Здравствуйте, iGrog, Вы писали:
F>>>> Тут надо понять сразу что именно сильно "тормозит". G>>>Как это можно узнать точно? F>> Пробовать.
G>Вот профайлер что показывает:
G>
G>Можно что-нибудь сделать для ускорения?
ИМХО, стек не соответствует выражению в примере. Если там сложное выражение, то можно попробовать использовать CompiledQuery. Только, не знаю как BLT (скорее всего также), а LINQtoSQL компилирует при первом запросе.
G> db.SetCommand("SELECT title FROM goods WHERE GID != 1");
G> var list = db.ExecuteScalarList<String>();
G> var goods = db.Good.Where(el => el.GID != 1).ToList();
G>
А тебе не кажется что вот эти два запроса получают разные данные?
В первом случае ты получаешь только строки, а во втором случае целые объекты.
Также очень хочется посмотреть на SQL который получается во втором случае и сколько строк в базе. Ибо получаешь ты их все кроме одной.
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, WolfHound, Вы писали:
WH>Здравствуйте, iGrog, Вы писали:
G>>
G>> db.SetCommand("SELECT title FROM goods WHERE GID != 1");
G>> var list = db.ExecuteScalarList<String>();
G>> var goods = db.Good.Where(el => el.GID != 1).ToList();
G>>
WH>А тебе не кажется что вот эти два запроса получают разные данные? WH>В первом случае ты получаешь только строки, а во втором случае целые объекты. WH>Также очень хочется посмотреть на SQL который получается во втором случае и сколько строк в базе. Ибо получаешь ты их все кроме одной.
База SQL Server 2008 R2
Строка подключения: Data Source=SERVER2\R2SERVERSQL;Initial Catalog=mydb;User Id=user;Password=password;
providerName="System.Data.SqlClient
В таблице ровно 2(две!) записи с GID == 1 и GID == 2
Сделал так:
Кандидат №1 в таких случаях это — времемя на джиттинг кода, и это стоит проверять в первую очередь. Используй NGen для сборки BLToolkit. У меня это значительно сокращает время аналогичного лага как в твоём случае.
Я не использую это в своей практике. И ещё NGen выдаёт кучу экзепшнов, — на что они влияют, и на что можно и можно ли вообще напоросться — я не в курсе. Может кто другой здесь в курсе и их можно смело игнорировать.
Кстати, у меня похожая проблема.
1. Рестартую сервер
2. Жду пока донимется ASP.NET
3. Сервер отдаёт первую страницу на которой у меня выполняется ajax запрос к данным
4. Первый раз этот ajax запрос, также как и автора, выполняется не менее 5 секунд. После этого всё грузится мгновенно.
BLT внутри что-то билдит при первом обращении?
G>Запускал десятки раз в debug/release — время LINQа всегда около 5 секунд. G>Почему так и как сделать, что бы было быстро?
F> Кандидат №1 в таких случаях это — времемя на джиттинг кода, и это стоит проверять в первую очередь. Используй NGen для сборки BLToolkit. У меня это значительно сокращает время аналогичного лага как в твоём случае.
Здравствуйте, Маслаков Михаил, Вы писали:
ММ>Кстати, у меня похожая проблема. ММ>1. Рестартую сервер ММ>2. Жду пока донимется ASP.NET ММ>3. Сервер отдаёт первую страницу на которой у меня выполняется ajax запрос к данным ММ>4. Первый раз этот ajax запрос, также как и автора, выполняется не менее 5 секунд. После этого всё грузится мгновенно.
ММ>BLT внутри что-то билдит при первом обращении?
Здравствуйте, iGrog, Вы писали:
G>http://blogs.msdn.com/b/clrcodegeneration/archive/2010/04/27/ngen-getting-started-with-ngen-in-visual-studio.aspx G>Спасибо, fddima
Да не за что. Вообще, имхо, это не самый лучший способ. NGen генерирует на каждую версию сборку у себя в закромах, так что по хорошему надо не забывать ngen uninstall делать, дабы не собирать мусор на диске C:. И вообще NGen — это ближе к стадии развёртывания приложения, и использовать его нужно осторожно — можно получить больше минусов чем плюсов. Собтсвенно я думаю будет достаточно разок сделать ngen bltoolkit, той версии которую используешь, особенно в случае если активно BLT не меняешь — то и перегенерировать каждый раз ничего не надо. Соответственно и post-build event-ы не нужны будут.
А NGen для твоего клиентского приложения по времени запуска думаю что большого результата не даст, хотя всё зависит от его размеров конечно.