【发布时间】:2020-02-01 20:55:03
【问题描述】:
这个问题比实际更理论,但仍然如此。
我一直在寻找机会从字符串内存分配的角度改进以下代码:
/* Output for n = 3:
*
* ' #'
* ' ##'
* '###'
*
*/
public static string[] staircase(int n) {
string[] result = new string[n];
for(var i = 0; i < result.Length; i++) {
var spaces = string.Empty.PadLeft(n - i - 1, ' ');
var sharpes = string.Empty.PadRight(i + 1, '#');
result[i] = spaces + sharpes;
}
return result;
}
PadHelper 是方法,最终每次迭代都会在后台调用两次。
所以,如果我错了,请纠正我,但似乎每次迭代至少分配了 3 次内存。
任何代码改进都将受到高度赞赏。
【问题讨论】:
-
这似乎有点挑错了树,因为这种方法的最大胜利将是完全消除
string[],以及所有用于生成它的东西。如果直接用作输出,则最终结果是打印 9 个字符和 3 个换行符(嗯,X 和 Y 取决于n),这完全可以在没有任何显式分配的情况下完成。 (或者,更实际一点,因为打印单个字符效率很低,所有行只有一个字符串缓冲区。) -
也许你可以分配一个带有
n - 1空格的字符串和n在循环外锐化,然后为每个i返回一个子字符串,从偏移量i. -
是的,.NET 中的字符串是不可变的。因此,任何字符串操作都会导致新的分配。 StringBuilder 类可能在这里有所帮助
-
StringBuilder 在字符串分配方面始终是一个答案;我敢肯定你知道,所以显然你想要别的东西。好吧,由于您的字符串长度都相同,您可以声明一个
char[]数组,每次都填充它(只需在每次迭代中更改两个相邻元素),然后使用string(char[])constructor。 -
如果你让函数返回
IEnumerable<string>和yield return,那么你甚至不需要字符串数组。
标签: c# .net string optimization stringbuilder