You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何优化二维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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 02:59:55