如何优化C#嵌套foreach循环以缩短代码执行时间?
C#嵌套循环代码性能优化方案
原代码处理数百条记录耗时约1分钟,核心瓶颈在于重复的反射操作,以下是针对性的优化方案,可大幅降低执行时间:
优化后的代码
public static IEnumerable<ListviewDataViewModel> GetModelsList<T>(this IEnumerable<T> modelsList , IEnumerable<ListviewColumnViewModel> modelsColumn , Action<ListviewDataViewModel, T> listVwItemCallback = null) where T : class { if (modelsColumn == null || !modelsColumn.Any()) yield break; // 用yield break替代返回null,更符合IEnumerable的设计 // 提前缓存T类型对应的属性信息,只做一次反射 var type = typeof(T); var propertyCache = modelsColumn .Select(c => new { Column = c, Property = type.GetProperty(c.ModelProperty) }) .ToList(); // 预初始化结果列表,若能预估数量可设置Capacity减少扩容开销 var listItms = new List<ListviewDataViewModel>(); // 可选:如果modelsList是ICollection类型,直接设置容量 if (modelsList is ICollection<T> collection) listItms.Capacity = collection.Count; foreach (var d in modelsList) { var li = new ListviewDataViewModel(); // 直接使用缓存的属性信息,避免重复反射 foreach (var cacheItem in propertyCache) { var _col = string.Empty; if (cacheItem.Property != null) _col = (cacheItem.Property.GetValue(d) ?? string.Empty).ToString(); li.ColumnItem.Add(_col); } listVwItemCallback?.Invoke(li, d); listItms.Add(li); } return listItms; }
核心优化点说明
- 缓存反射结果:原代码每条数据、每个列都重复调用
GetType()和GetProperty(),这是最耗时的操作。优化后只对泛型类型T做一次反射,把列和对应的属性信息缓存起来,内部循环直接复用缓存,将反射的时间复杂度从O(n*m)降到O(m)(n是数据条数,m是列数)。 - 提前初始化结果列表:原代码第一次循环才初始化列表,提前创建可避免每次循环的null判断,同时如果能预估数据量,设置
Capacity可以减少列表动态扩容的内存开销。 - 替换返回null为yield break:返回
null不符合IEnumerable的设计规范,使用yield break返回空序列更安全,调用方无需额外判空。 - 减少重复对象创建:原代码内部循环每次都创建
type变量,现在直接复用提前获取的typeof(T)结果。
这些优化能把反射的开销降到最低,处理数百条数据的时间应该能轻松减半。
内容的提问来源于stack exchange,提问作者AungMyat Thu
相关产品推荐
相关产品推荐

