我想知道是否有人能够了解反射的方式以及动态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;
}
答案 0 :(得分:1)
请参阅here:
致电网站缓存。动态调用站点是代码中的一个位置,您可以在动态对象上执行类似+ b或a.b()的操作。 DLR缓存a和b的特征(通常是这些对象的类型)和有关操作的信息。如果先前已执行此类操作,则DLR将从缓存中检索所有必要信息以进行快速分派。