我有以下代码:
var array1 = [1, 2, 3, 4];
var array2 = [5, 6, 7, 8, 100];
var sum = array1.map((num, idx) => num + array2[idx]); // [6,8,10,12]
变量diag是记录列表
变量cas是具有大约50k项目的记录列表。
问题在于它太慢了。具有第一个where子句的部分需要大约4,6599ms,例如对于列表诊断中的3000条记录,它使得3000 * 4,6599 = 14秒。有优化代码的选项吗?
答案 0 :(得分:6)
您可以加快您强调的具体陈述
cas.Where(x => x.Datetime >= min && x.Datetime <= max).ToList();
通过cas
列表进行二进制搜索。首先按cas
预先排序Datetime
:
cas.Sort((a,b) => a.Datetime.CompareTo(b.Datetime));
然后为Record
创建比较器,它只比较Datetime
属性(实现假定列表中没有空记录):
private class RecordDateComparer : IComparer<Record> {
public int Compare(Record x, Record y) {
return x.Datetime.CompareTo(y.Datetime);
}
}
然后你可以翻译你的Where
条款:
var index = cas.BinarySearch(new Record { Datetime = min }, new RecordDateComparer());
if (index < 0)
index = ~index;
var possibleResults = new List<Record>();
// go backwards, for duplicates
for (int i = index - 1; i >= 0; i--) {
var res = cas[i];
if (res.Datetime <= max && res.Datetime >= min)
possibleResults.Add(res);
else break;
}
// go forward until item bigger than max is found
for (int i = index; i < cas.Count; i++) {
var res = cas[i];
if (res.Datetime <= max &&res.Datetime >= min)
possibleResults.Add(res);
else break;
}
想法是找到Datetime
与min
相等或更高的第一条记录,BinarySearch
。如果找到完全匹配 - 它返回匹配元素的索引。如果未找到 - 它返回负值,可以使用~index
操作将其转换为大于目标的第一个元素的索引。
当我们找到该元素时,我们可以直接前进列表并抓取项目,直到找到Datetime
大于max的项(因为列表已排序)。我们还需要稍微退一步,因为如果有重复 - 二元搜索不需要返回第一个,所以我们需要向后搜索可能的重复项。
其他改进可能包括:
将活动代码置于for循环之外的Dictionary
(由Value
键控),从而将代码Where
替换为Dictionary.ContainsKey
。
正如@ Digitalsa1nt的评论中所建议的那样 - 使用Parallel.For
,PLINQ或任何类似技术并行化foreach循环。这是并行化的完美案例,因为循环只包含CPU绑定工作。您需要进行一些调整以使其成为线程安全的,例如使用errors
的线程安全集合(或锁定添加它)。
答案 1 :(得分:0)
尝试在列表中添加AsNoTracking
$request->all();
方法可以节省执行时间和内存使用量。当我们从数据库中检索大量数据时,应用此选项确实很重要。
if($res['member_id']){
Academico::where('member_id', $res['member_id'])->delete();
}
答案 2 :(得分:0)
您可以在此处进行一些改进。 它可能只是一个小的性能提升,但您应该尝试使用groupby而不是在这种情况下的位置。
所以你应该有这样的东西:
cas.GroupBy(x => x.DateTime >= min && x.DateTime <= max).Select(h => h.Key == true);
这通常适用于通过列表查找不同的值,但在您的情况下,我不确定它在使用子句时是否会为您提供任何好处。
您可以在整个代码中执行其他一些操作: