如何缩短VB.NET中5000条数据的计算时间(目标≤1秒)
代码优化建议(从5秒降至1秒内)
核心优化方向:减少重复遍历、降低内存开销、优化并行效率
预分组替代重复查询
原代码每次并行循环都调用.stresses.FindAll遍历全集合,5000个标签会产生5000次全量遍历,时间复杂度为O(n*m)。先一次性按Tag0D分组,直接获取每组数据:With gOutputStresses_LC(0) ' 替换原UniqueTagsList,直接分组 Dim groupedStresses = .stresses.GroupBy(Function(s) s.Tag0D).ToList() Dim options As New ParallelOptions() options.MaxDegreeOfParallelism = Environment.ProcessorCount ' 利用全部CPU核心 Parallel.ForEach(groupedStresses, options, Sub(group) Dim tstresses = group.ToList() ' 后续操作直接使用tstresses,无需再执行FindAll简化排序逻辑
原代码先升序排序再反转,直接改用降序排序一步完成,减少一次遍历操作:' 替换tstresses.Sort(...)和Reverse() tstresses = tstresses.OrderByDescending(Function(x) x.Sxx).ToList()消除冗余的回写查找
clsMSHStress是引用类型,修改tstresses中的元素会直接同步到原stresses集合。删除Else分支末尾的For p循环,彻底避免每次查找元素的全量遍历:' 删除以下冗余代码块 'For p As Integer = 0 To tstresses.Count - 1 ' .stresses(.stresses.FindIndex(Function(s) s.Tag0D = tstresses(p).Tag0D And s.Tag2D = tstresses(p).Tag2D)) = tstresses(p) 'Next避免不必要的列表创建
原代码创建delta列表查找最大差值索引,可直接遍历计算,省去列表内存分配和额外遍历:' 替换原delta列表相关代码 Dim maxDelta As Double = Double.MinValue Dim splitIdx As Integer = 0 For k As Integer = 1 To tstresses.Count - 1 Dim currentDelta = tstresses(k).Sxx - tstresses(k - 1).Sxx If currentDelta > maxDelta Then maxDelta = currentDelta splitIdx = k End If Next合并遍历计算,减少重复遍历
计算平均值时避免单独调用Sum,在遍历过程中直接累加总和,减少一次遍历:' 替换error_ <10时的平均值计算 Dim sum As Double = 0 For Each s In tstresses sum += s.Sxx Next AverageVal = sum / tstresses.Count优化变量作用域
将AverageVal、error_等变量移到并行循环内部,避免线程安全问题,同时减少重复初始化开销:Parallel.ForEach(groupedStresses, options, Sub(group) Dim tstresses = group.ToList() Dim AverageVal As Double = 0 Dim error_ As Double = 0 ' 后续逻辑使用内部变量
修改后的完整示例代码
With gOutputStresses_LC(0) Dim groupedStresses = .stresses.GroupBy(Function(s) s.Tag0D).ToList() Dim options As New ParallelOptions() options.MaxDegreeOfParallelism = Environment.ProcessorCount Parallel.ForEach(groupedStresses, options, Sub(group) Dim tstresses = group.OrderByDescending(Function(x) x.Sxx).ToList() Dim AverageVal As Double = 0 Dim error_ As Double = 0 error_ = Math.Abs((tstresses(0).Sxx - tstresses.Last.Sxx) / (tstresses(0).Sxx + tstresses.Last.Sxx)) If error_ < 10 Then Dim sum As Double = 0 For Each s In tstresses sum += s.Sxx Next AverageVal = sum / tstresses.Count For Each c In tstresses c.Sxx = AverageVal Next Else Dim maxDelta As Double = Double.MinValue Dim splitIdx As Integer = 0 For k As Integer = 1 To tstresses.Count - 1 Dim currentDelta = tstresses(k).Sxx - tstresses(k - 1).Sxx If currentDelta > maxDelta Then maxDelta = currentDelta splitIdx = k End If Next ' 计算前半部分平均值 AverageVal = 0 For g As Integer = 0 To splitIdx - 1 AverageVal += tstresses(g).Sxx Next AverageVal = AverageVal / splitIdx For g As Integer = 0 To splitIdx - 1 tstresses(g).Sxx = AverageVal Next ' 计算后半部分平均值 AverageVal = 0 For g As Integer = splitIdx To tstresses.Count - 1 AverageVal += tstresses(g).Sxx Next AverageVal = AverageVal / (tstresses.Count - splitIdx) For g As Integer = splitIdx To tstresses.Count - 1 tstresses(g).Sxx = AverageVal Next End If End Sub) End With
内容的提问来源于stack exchange,提问作者Anas Ahmed
相关产品推荐
相关产品推荐

