У меня есть большая коллекция предметов LiteDB. Я просто хочу найти последний добавленный по некоторым критериям. Критерии в лямбда-выражении. Моя проблема в том, что это заняло очень много времени (сейчас около 2-3 секунд), и у меня просто есть тестирование базы данных. В полном режиме будет в 10 раз больше значений.
Мой код теперь с отметками времени:
var values = db.GetCollection<ExtendedValue>(IncomingValueCollection);
if (values.Count() > 0) {
Stopwatch sw = new Stopwatch();
sw.Reset();
sw.Start();
var expressedVals = values.Find(lambda);
sw.Stop();
Debug.WriteLine("find values " + sw.ElapsedMilliseconds);
sw.Reset();
sw.Start();
var inOrder = expressedVals.OrderByDescending(x => x.TimeCaptured).Take(5);
sw.Stop();
Debug.WriteLine("order " + sw.ElapsedMilliseconds);
sw.Reset();
sw.Start();
var result = inOrder.First();
sw.Stop();
Debug.WriteLine("last " + sw.ElapsedMilliseconds);
return result;
//withouth stopwatch
//return values.Find(lambda).OrderByDescending(x => x.TimeCaptured).First();
}
и результат:
find values 0
order 0
last 2399
Так что ясно, что значение выбора занимает большую часть времени.
Я пробовал:
- Просто используйте .First () для orderEnum, без изменений
- используйте Take ( x ) или нет,без изменений
- Преобразуйте его в массив или список, а затем выберите первый, это займет немного больше времени, но ничего существенного
Я думаю, что .First () создает массив из enum изатем выберите первый пункт. Есть ли способ выбрать элемент без создания целого массива и создания большого лага?
РЕДАКТИРОВАТЬ: Согласно комментариям Мэтью Уотсона, я отредактировал код, чтобы выяснить, что мое лямбда-выражение принимаетБольшая часть времени и вывод о том, что метод First () занимает больше всего времени, является ошибкой. Это происходит только потому, что он выполняет весь запрос сразу.
if (values.Count() > 0) {
Stopwatch sw = new Stopwatch();
sw.Reset();
sw.Start();
var expressedVals = values.Find(lambda).ToList();
sw.Stop();
Debug.WriteLine("find values " + sw.ElapsedMilliseconds);
sw.Reset();
sw.Start();
var inOrder = expressedVals.OrderByDescending(x => x.TimeCaptured).ToList();
sw.Stop();
Debug.WriteLine("order " + sw.ElapsedMilliseconds);
sw.Reset();
sw.Start();
var result = expressedVals.First();
sw.Stop();
Debug.WriteLine("last " + sw.ElapsedMilliseconds);
return result;
//withouth stopwatch
//return values.Find(lambda).OrderByDescending(x => x.TimeCaptured).First();
с результатом
find values 2395
order 4
last 0
Так что я думаю, что я не могу сделать это таким образом, я должен создать обходной путь.