反思和动态LINQ的表现 - 第一次' vs'后续运行'

时间:2015-09-15 18:53:18

标签: c# performance linq dynamic reflection

我想知道是否有人能够了解反射的方式以及动态LINQ是否会导致第一次使用' vs'后续用法'。

以下是我的测试用例的片段。 我的目的是运行查询10次,每次迭代使用不同的输入参数。我注意到的是,动态LINQ的第一次迭代总是很慢,但后续运行速度更快。

我的问题不是针对Dynamic LINQ,而是反射。 是.Net在第一次使用时缓存了什么? (例如动态LINQ表达式tress,反射PropertyInfo) 如果这是一个多线程应用程序怎么办? 这个缓存在哪里/怎么样?例如在一些当地的背景下?本地线程?在全球范围内?

BTW,我们的前端是一个WebApi应用程序...所以我想知道我们是否能够在后续的Web请求中利用性能提升?

    var sw = new Stopwatch();
    for (var i = 1; i <= iterations; i++)
    {
        //--- Part 1: Setup filter inputs 
        // code removed for brevity (e.g. startDate, endDate, location, etc.)

        //--- Part 2: Regular LINQ
        elapsedTime = 0;
        RunStandardLinq(sw, startDate, endDate, location, mrnIds, out expected, out elapsedTime);
        elapsedTimeRegularLinq += elapsedTime;

        //--- Part 3: Dynamic LINQ
        elapsedTime = 0;
        RunDynamicLinq(sw, startDate, endDate, location, mrnIdsString, out actual, out elapsedTime);
        elapsedTimeDynamicLinq += elapsedTime;
    }

以下是LINQ查询

private void RunStandardLinq(Stopwatch sw, DateTime startDate, DateTime endDate, string location, string[] mrnIds,
    out IEnumerable<Encounter> results, out double elapsedMilliseconds)
{
    //--- Regular LINQ operations - must match the Dynamic LINQ
    sw.Restart();
    var resultsEnumerable = _sampleData
                    .Where(e => e.Admission.Date >= startDate)
                    .Where(e => e.Admission.Date < endDate)
                    .Where(e => e.Location == location)
                    .Where(e => mrnIds.Contains(e.PhnIdentifier.Id))
                    .OrderByDescending(e => e.PhnIdentifier.Code)
                   ;
    results = resultsEnumerable.ToList();
    sw.Stop();
    elapsedMilliseconds = sw.Elapsed.TotalMilliseconds;
}


private void RunDynamicLinq(Stopwatch sw, DateTime startDate, DateTime endDate, string location, string mrnIdsString,
    out IEnumerable<Encounter> results, out double elapsedMilliseconds)
{
    //--- Dynamic LINQ operations - must match the Regular LINQ
    sw.Restart();
    IEnumerable resultsEnumerable = DynamicQueryable.OrderBy(_sampleData
                    .Where(@"Admission.Date >= @0", startDate)
                    .Where(@"Admission.Date < @0", endDate)
                    .Where(string.Format(@"Location=""{0}""", location))
                    .Where(@"PhnIdentifier.Id in " + mrnIdsString),
                    "PhnIdentifier.Code descending");

    results = resultsEnumerable.Cast<Encounter>().ToList(); 
    sw.Stop();
    elapsedMilliseconds = sw.Elapsed.TotalMilliseconds;
}

1 个答案:

答案 0 :(得分:1)

请参阅here

  

致电网站缓存。动态调用站点是代码中的一个位置,您可以在动态对象上执行类似+ b或a.b()的操作。 DLR缓存a和b的特征(通常是这些对象的类型)和有关操作的信息。如果先前已执行此类操作,则DLR将从缓存中检索所有必要信息以进行快速分派。