二维数组连续重复元素搜索性能优化方案咨询
如何用Task.Run优化二维数组连续重复元素查找的性能?
我编写了一段C#代码,用于在二维数组中查找行或列内连续3个重复的元素,包含SearchInRows和SearchInCols两个方法,代码运行正常。后续我会在循环中反复调用这两个方法并修改数组,现咨询是否可通过Task.Run等方式优化代码性能。
原代码
private static bool SearchInRows(int[,] matrix) { int count = 1; int repeatElement = int.MaxValue; //Search in rows for (int i = 0; i < matrix.GetLength(0); i++) { repeatElement = matrix[i, 0]; for (int j = 1; j < matrix.GetLength(1); j++) { if (repeatElement == matrix[i, j]) { count++; if (count >= 3) { Console.WriteLine($"Repeated elements are in positions i:{i}, j:{j - 2}, {j - 1}, {j}"); return true; } } else { repeatElement = matrix[i, j]; count = 1; } } } return false; } private static bool SearchInCols(int[,] matrix) { int count = 1; int repeatElement = int.MaxValue; //Search in cols for (int j = 0; j < matrix.GetLength(1); j++) { repeatElement = matrix[0, j]; for (int i = 1; i < matrix.GetLength(0); i++) { if (repeatElement == matrix[i, j]) { count++; if (count >= 3) { Console.WriteLine($"Repeated elements are in positions j:{j}, i:{i-2}, {i-1}, {i}"); return true; } } else { repeatElement = matrix[i, j]; count = 1; } } } return false; }
后续计划执行的逻辑
while (!SearchInRows(matrix) && !SearchInCols(matrix)) { SearchInRows(matrix); SearchInCols(matrix); //modify the matrix }
优化方案:用Task.Run实现并行查找
可以通过并行执行行和列的查找任务来提升性能,但需要注意以下几点:
- 任务独立性:
SearchInRows和SearchInCols仅读取数组,不修改内容,因此可以安全地并行执行,将两次查找的时间重叠。 - 提前终止逻辑:原逻辑中只要任意一个方法返回
true就停止循环,并行时可以用Task.WhenAny获取先完成的任务,一旦发现有结果返回true,即可终止流程。 - 线程安全的输出:原方法中直接调用
Console.WriteLine,并行时多个任务同时写控制台会导致输出混乱,建议将结果(是否找到、位置信息)封装后返回,在主线程统一输出。 - 数组修改的同步:修改数组前必须确保所有查找任务都已完成,避免读取和修改操作冲突。
优化后的代码示例
首先,定义一个结构体封装查找结果:
public struct SearchResult { public bool Found { get; set; } public string Message { get; set; } }
修改查找方法,返回SearchResult而不是直接输出:
private static SearchResult SearchInRows(int[,] matrix) { int count = 1; int repeatElement = int.MaxValue; for (int i = 0; i < matrix.GetLength(0); i++) { repeatElement = matrix[i, 0]; for (int j = 1; j < matrix.GetLength(1); j++) { if (repeatElement == matrix[i, j]) { count++; if (count >= 3) { return new SearchResult { Found = true, Message = $"Repeated elements are in positions i:{i}, j:{j - 2}, {j - 1}, {j}" }; } } else { repeatElement = matrix[i, j]; count = 1; } } } return new SearchResult { Found = false }; } private static SearchResult SearchInCols(int[,] matrix) { int count = 1; int repeatElement = int.MaxValue; for (int j = 0; j < matrix.GetLength(1); j++) { repeatElement = matrix[0, j]; for (int i = 1; i < matrix.GetLength(0); i++) { if (repeatElement == matrix[i, j]) { count++; if (count >= 3) { return new SearchResult { Found = true, Message = $"Repeated elements are in positions j:{j}, i:{i-2}, {i-1}, {i}" }; } } else { repeatElement = matrix[i, j]; count = 1; } } } return new SearchResult { Found = false }; }
修改循环逻辑,并行执行查找任务:
while (true) { // 并行启动行、列查找任务 var rowTask = Task.Run(() => SearchInRows(matrix)); var colTask = Task.Run(() => SearchInCols(matrix)); // 等待任意一个任务完成 var completedTask = await Task.WhenAny(rowTask, colTask); var result = completedTask.Result; // 如果找到重复元素,输出结果并终止循环 if (result.Found) { Console.WriteLine(result.Message); // 等待另一个任务自然结束(可选,避免后台任务残留) await Task.WhenAll(rowTask, colTask); break; } // 两个任务都未找到,等待全部完成后再修改数组 await Task.WhenAll(rowTask, colTask); // modify the matrix }
注意事项
- 性能收益场景:当数组规模较大时,并行查找的收益才明显;如果数组很小,任务调度的开销可能反而会降低性能。
- 取消任务(可选):如果需要更精细的控制,可以使用
CancellationToken来取消未完成的任务,避免不必要的计算。 - 线程安全:确保数组在查找过程中不会被修改,必须等所有查找任务完成后再执行修改操作。
内容的提问来源于stack exchange,提问作者Palamar66
相关产品推荐
相关产品推荐

