0

我有大量的 LiteDB 项目集合。我只想找到按某些标准添加的最后一个。标准在 lambda 表达式中。我的问题是,它花了很长时间(现在大约 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

所以很明显,选择值需要大部分时间。

我努力了:

  • 只需在orderedEnum上使用.First(),没有变化
  • 使用 Take( x ) 与否,没有变化
  • 将其转换为数组或列表,然后选择第一个,这需要更长的时间,但没什么意义

我认为, .First() 从枚举创建数组,然后选择第一项。有没有办法在不生成整个数组并造成大滞后的情况下选择项目?

编辑: 根据 Matthew Watson 的评论,我编辑了代码,发现我的 lambda 表达式花费了大部分时间和结论,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

所以我认为,我不能这样做,我必须创建解决方法。

4

0 回答 0