如何优化二维char数组转字符串性能?当前耗时约950ms
问题描述
我需要将256×256的char二维数组所有元素提取并转换为字符串,当前代码中的ExtractA()函数平均耗时约950ms,希望找到更快的实现方式或优化方案。
核心性能瓶颈代码片段:
for (int ii = 0; ii < 255; ii++) { for (int i = 0; i < 255; i++) { Export = Export + BufferC[i, ii]; } }
完整代码上下文:
public static string ExportBuffer(int Buffer, int Line, int Dimension = 2, int Start = 0, int End = 255) { string Export = "Test"; for (int ii = 0; ii < 255; ii++) { for (int i = 0; i < 255; i++) { BufferC[i, ii] = 'A'; } } switch (Buffer) { default: throw new NotImplementedException("The buffer selected does not exist."); case 00: ExtractDisplayBuffer(); break; case 01: ExtractBufferA(); break; case 02: ExtractBufferB(); break; case 03: ExtractBufferC(); break; } void ExtractDisplayBuffer() { switch (Dimension) { case 0: ExtractX(); break; case 1: ExtractY(); break; case 2: ExtractA(); break; } void ExtractX() { for (int i = Start; i < End; i++) { Export = Export + BufferC[i, ii]; } } void ExtractY() { for (int i = Start; i < End; i++) { Export = Export + BufferC[i, ii]; } } void ExtractA() { for (int ii = 0; ii < 255; ii++) { for (int i = 0; i < 255; i++) { Export = Export + BufferC[i, ii]; } } } } void ExtractBufferA() { switch (Dimension) { case 0: ExtractX(); break; case 1: ExtractY(); break; case 2: ExtractA(); break; } void ExtractX() { for (int i = Start; i < End; i++) { Export = Export + BufferC[i, ii]; } } void ExtractY() { for (int i = Start; i < End; i++) { Export = Export + BufferC[i, ii]; } } void ExtractA() { for (int ii = 0; ii < 255; ii++) { for (int i = 0; i < 255; i++) { Export = Export + BufferC[i, ii]; } } } } void ExtractBufferB() { switch (Dimension) { case 0: ExtractX(); break; case 1: ExtractY(); break; case 2: ExtractA(); break; } void ExtractX() { for (int i = Start; i < End; i++) { Export = Export + BufferC[i, ii]; } } void ExtractY() { for (int i = Start; i < End; i++) { Export = Export + BufferC[i, ii]; } } void ExtractA() { for (int ii = 0; ii < 255; ii++) { for (int i = 0; i < 255; i++) { Export = Export + BufferC[i, ii]; } } } } void ExtractBufferC() { switch (Dimension) { case 0: ExtractX(); break; case 1: ExtractY(); break; case 2: ExtractA(); break; } void ExtractX() { for (int i = Start; i < End; i++) { Export = Export + BufferC[i, ii]; } } void ExtractY() { for (int i = Start; i < End; i++) { Export = Export + BufferC[i, ii]; } } void ExtractA() { for (int ii = 0; ii < 255; ii++) { for (int i = 0; i < 255; i++) { Export = Export + BufferC[i, ii]; } } } } return Export; }
优化方案
1. 替换字符串拼接为StringBuilder
string是不可变类型,每次Export = Export + ...都会创建新字符串,带来大量内存分配和GC开销,这是性能瓶颈的核心原因。使用StringBuilder可变字符缓冲区可以避免这个问题。
修改后的ExtractA()示例:
void ExtractA() { // 预分配足够容量:初始"Test"4个字符 + 256*256数组元素 var sb = new StringBuilder(4 + 256*256); sb.Append("Test"); for (int ii = 0; ii < 256; ii++) // 修正循环边界:原来<255会少遍历一行 { for (int i = 0; i < 256; i++) { sb.Append(BufferC[i, ii]); } } Export = sb.ToString(); }
2. 直接使用char数组构造字符串
如果不需要中间拼接"Test"以外的内容,还可以直接复制二维数组到一维char数组,再用new string()构造,这是效率最高的方式之一:
void ExtractA() { int totalLength = 4 + 256*256; char[] resultArray = new char[totalLength]; // 先复制初始的"Test" "Test".CopyTo(0, resultArray, 0, 4); int index = 4; for (int ii = 0; ii < 256; ii++) { for (int i = 0; i < 256; i++) { resultArray[index++] = BufferC[i, ii]; } } Export = new string(resultArray); }
3. 消除重复代码
原代码中ExtractBufferA/B/C等方法逻辑完全重复,可以提取为通用方法,减少冗余同时方便后续优化:
// 提取通用的提取逻辑 void ExtractCommon(int dimension) { var sb = new StringBuilder(4 + 256*256); sb.Append("Test"); switch (dimension) { case 0: // 修正原代码变量作用域问题,ii应为传入的Line参数 for (int i = Start; i < End; i++) { sb.Append(BufferC[i, Line]); } break; case 1: // 修正原代码变量作用域问题,遍历对应列 for (int i = Start; i < End; i++) { sb.Append(BufferC[Line, i]); } break; case 2: for (int ii = 0; ii < 256; ii++) { for (int i = 0; i < 256; i++) { sb.Append(BufferC[i, ii]); } } break; } Export = sb.ToString(); } // 原switch分支可简化为: switch (Buffer) { default: throw new NotImplementedException("The buffer selected does not exist."); case 00: case 01: case 02: case 03: ExtractCommon(Dimension); break; }
4. 其他细节优化
- 修正循环边界:原代码中
ii < 255和i < 255只遍历了255个元素,应该改为ii < 256或ii <=255,确保完整遍历256×256的数组。 - 移除测试用初始化:原代码开头的
BufferC赋值循环如果仅为测试用途,可直接移除以减少不必要的计算。
内容的提问来源于stack exchange,提问作者user21161268
相关产品推荐
相关产品推荐

