Забрать первый предмет из перечисленного заняло много времени - PullRequest
0 голосов
/ 06 октября 2019

У меня есть большая коллекция предметов 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

Так что я думаю, что я не могу сделать это таким образом, я должен создать обходной путь.

...