c# - 在 C# 中优化循环字符串连接的性能

标签 c# string performance string-concatenation

我有一个处理一些历史数据的应用程序。
我做了一些性能分析,并将以下功能确定为新的瓶颈:

public string GenerateSaveStringOptimized()
{
    StringBuilder saveString = new StringBuilder();
    saveString.Append( $"{this.TimeOfDay},{this.DayOfMonth},{this.DayOfYear},");
    foreach (float value in this.MovingAverage3h) saveString.Append($"{value},");
    foreach (float value in this.MovingAverage6h) saveString.Append($"{value},");
    foreach (float value in this.MovingAverage1d) saveString.Append($"{value},");
    foreach (float value in this.MovingAverage6d) saveString.Append($"{value},");
    foreach (float value in this.MovingAverage12d) saveString.Append($"{value},");
    foreach (float value in this.MovingAverage24d) saveString.Append($"{value},");
    foreach (float value in this.MovingAverage48d) saveString.Append($"{value},");
    foreach (float value in this.MovingAverage96d) saveString.Append($"{value},");
    foreach (float value in this.RSI3h) saveString.Append($"{value},");
    foreach (float value in this.RSI6h) saveString.Append($"{value},");
    foreach (float value in this.RSI1d) saveString.Append($"{value},");
    foreach (float value in this.RSI6d) saveString.Append($"{value},");
    foreach (float value in this.RSI12d) saveString.Append($"{value},");
    foreach (float value in this.Momentum1h) saveString.Append($"{value},");
    foreach (float value in this.SpotPrices1h) saveString.Append($"{value},");
    foreach (float value in this.BuyPrices1h) saveString.Append($"{value},");
    foreach (float value in this.SellPrices1h) saveString.Append($"{value},");
    saveString.Append($"{this.Label}");
    return saveString.ToString();
}
enter image description here
结果将是 csv 格式的字符串,例如:

0,1,1,0.4916667,0.4916667,0.4916667,0.4916667,0.4916667,0.49,0.49,0.49,0.49,0.4897351, [...]


每个数组都包含 25 个浮点值,因此代码类似于以下伪代码:
for (int i = 0; i < 17; i++)
{
    for (b = 0; b < 25 b++)
    {
        saveString.Append("Value,")
    }
}
每次调用该函数都会产生 17 * 25 = 425 个字符串连接!
有没有办法优化它?
最高性能的食客似乎是“等待 cpu”和“AppendformatHelper”,这是来自 StringBuilder 的内置方法。不幸的是,我不知道如何轻松对待它
enter image description here
也许使用以下硬编码设置?
saveString.Append($"{MA3h[0]},{MA3h[1]},{MA3h[2]},...");
saveString.Append($"{MA6h[0]},{MA6h[1]},{MA6h[2]},...");
saveString.Append($"{MA1d[0]},{MA1d[1]},{MA1d[2]},...");
使用以下循环取得了巨大的成功:
foreach (float value in this.RSI1d)
{
    saveString.Append(value.ToString());
    saveString.Append(',');
}
非常感谢 user1672994、Guru Stron 和 Theodor Zoulias
评论中的其他提及也将被尝试。

最佳答案

预分配足够的容量。

StringBuilder saveString = new StringBuilder(100000);
不要使用格式或插值。
saveString.Append(this.TimeOfDay).Append(',').Append(this.DayOfMonth).Append(',').Append(this.DayOfYear).Append(',');
在所有循环中执行类似的替换。
foreach (float value in this.MovingAverage3h) saveString.Append(value).Append(',');
不要使用格式或插值。
saveString.Append(this.Label);
Append方法具有接受 float 的重载,所以不会有拳击。

关于c# - 在 C# 中优化循环字符串连接的性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63342273/

相关文章:

c# - Entity Framework 4 部分 SaveChanges

c# - 如何将 ItemsControl(在网格外)绑定(bind)到网格?

Linux 切字符串

objective-c - 如何在保留斯堪的纳维亚字母的同时一直为 SQLite 正确编码 NSString

javascript - 如何从字符串中提取特定文本。困难的部分是所需的文本会定期更改

c# - 为什么具有可为空值的结构的 HashSet 非常慢?

linux - 为什么RAM的写入速度远低于上面所说的?

c# - SharpDX vs SlimDX 用于游戏开发?

c# - 在 Microsoft Teams 中机器人发送自适应卡片时如何更改通知文本?

java - 当找到多个集合的交集时,使用retainAll()的最快顺序