将数组转换为多行字符串的最快方法

3
什么是将数组元素导出到 .csv Excel 文件的最有效方式?目前我正在这样做,但速度非常慢。感谢您的支持。
int FrameWidth = 640;
int FrameHeight = 480;
Int16[] Values;  // 640 x 480, 307200 elements

/*
.. processing ...... 
*/

//Exporting Values to .csv file
string string2csv = null;
for (int y = 0; y < FrameHeight; y++)
{
    for (int x = 0; x < FrameWidth; x++)
    {
        string2csv = string2csv + Values[y * FrameWidth + x] + ";";
    }
    string2csv = string2csv + "\n";
}
File.WriteAllText("string2csv.csv", string2csv);

3
一种选择是使用 StringBuilder 替代 + - D Stanley
1
使用String.Join方法 更多信息 - CPUFry
@DriesVB 请注意,String.Join 内部使用了 StringBuilder - D Stanley
2
不要手动处理。使用类库,例如 CSV Helper ... - Jeff Mercado
2个回答

3

其中一种替代方法是将File.WriteAllLinesstring.Join组合使用;

File.WriteAllLines ("test.txt", 
    Values.Select((x,i) => new {x, i})
          .GroupBy(x => x.i / FrameWidth)
          .Select(grp => string.Join(";", grp.Select(y => y.x)))
);

它将选择数组中的所有元素和索引。 然后按行分组(通过将索引除以列数计算)。 分组的值然后使用 ; 连接成每行一个字符串,然后所有行都被输入到 File.WriteAllLines 中。

StringBuilder似乎是最快的,只用了27毫秒,然后是Joachim的,用了38毫秒,而我的解决方案则用了21,496毫秒 :) 我非常感谢你们所有人的评论!你们都很棒! - atteee

2

"最有效"的方法需要试错,但一个简单的替代方法是使用 StringBuilder

StringBuilder string2csv = new StringBuilder();
for (int y = 0; y < FrameHeight; y++)
{
    for (int x = 0; x < FrameWidth; x++)
    {
        string2csv.Append(Values[y * FrameWidth + x] + ";");
    }
    string2csv.Append("\n");
}

使用+添加字符串会为新字符串分配内存,然后将两个字符串的内容复制到新内存中。StringBuilder在内存中预先分配缓冲区,并向缓冲区添加字符,必要时扩展它。当添加大量字符串时,内存分配和复制要少得多。
这可能已经"足够快"了。除此之外,您需要获取一个良好的分析器来查看代码花费最多时间的部分,并攻击该部分。很可能您的"processing..."块是瓶颈,而不是CSV输出。

2
你甚至不需要这样做。他正在构建文件内容的字符串,而实际上他可以直接写入文件。 - Jeff Mercado
@JeffMercado 不确定那样会更有效率。 - paparazzo
2
为了优化,根据输入数组的大小(约5 * 307K字节),设置StringBuilder的初始容量非常重要。 - Steve
@JeffMercado: 嗯,我一直以为尽可能减少 I/O 操作会更快... 将成千上万的写操作写入文件流怎么比将所有内容缓存到内存中并进行单次写操作更快呢? 虽然我认识到这些写操作是有点被缓存的... - code4life
I/O 的数量无论哪种方式都差不多 - 唯一的区别是你是在循环内进行 I/O 还是在内存中构建一个大字符串,然后一次性将其全部输出。 - D Stanley
显示剩余7条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接