[英]Performance optimizing looped string concatenations in c#
我有一个处理一些历史数据的应用程序。 我进行了一些性能分析,并将以下 function 确定为新的瓶颈:
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();
}
结果将是 csv 格式的字符串,例如:
0,1,1,0.4916667,0.4916667,0.4916667,0.4916667,0.4916667,0.49,0.49,0.49,0.49,0.4897351, [...]
每个 arrays 都包含 25 个浮点值,因此代码类似于以下伪代码:
for (int i = 0; i < 17; i++)
{
for (b = 0; b < 25 b++)
{
saveString.Append("Value,")
}
}
对于该函数的每次调用,都会产生 17 * 25 = 425 个字符串连接!
有没有办法优化它?
顶级性能消耗者似乎是“等待 cpu”和“AppendformatHelper”,这是 StringBuilder 的内置方法。 不幸的是,我知道如何轻松对待它
也许使用如下硬编码设置?
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
的重载,因此不会出现装箱。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.