【发布时间】:2016-11-27 19:57:04
【问题描述】:
以下代码显示了构建电子表格的两种方法: 通过使用:
str = str + "\(number) ; "
或
str.append("\(number)");
两者都非常慢,因为我认为它们丢弃了两个字符串并制作了第三个字符串,这是前两个字符串的串联。 现在,如果我重复这个操作数十万次来增加一个电子表格......这会产生很多分配。
例如,以下代码在我的 MacBook Pro 2016 上执行需要 11 秒:
let start = Date()
var str = "";
for i in 0 ..< 86400
{
for j in 0 ..< 80
{
// Use either one, no difference
// str = str + "\(Double(j) * 1.23456789086756 + Double(i)) ; "
str.append("\(Double(j) * 1.23456789086756 + Double(i)) ; ");
}
str.append("\n")
}
let duration = Date().timeIntervalSinceReferenceDate - start.timeIntervalSinceReferenceDate;
print(duration);
我怎样才能解决这个问题而不必自己将双打转换为字符串?我已经坚持了 3 天...我的编程技能非常有限,您可能从上面的代码中可以看到...
我试过了:
var str = NSMutableString(capacity: 86400*80*20);
但是编译器告诉我:
Variable 'str' was never mutated; consider changing to 'let' constant
尽管
str.append("\(Double(j) * 1.23456789086756 + Double(i)) ; ");
显然,调用 append 不会改变字符串...
【问题讨论】:
-
我不认为
str.append或Double很慢...调用一行嵌套代码86400 * 80 = 6,912,000次会让任何事情看起来都很慢。 -
是的,我知道。这是因为我让一个字符串增长了 6,912,000...所以我进行了复制、分配等...删除了该部分(不添加,只需创建一个新字符串),看看它运行的速度有多快(0.043 秒)。分配是这里的杀手锏。所以我尝试将其设为具有容量的 NSMutableString,但显然,在 swift3 中追加副本而不是变异。
-
启用优化后,“不添加,只创建一个新字符串”代码将被删除。您的代码附加常量字符串需要多长时间,例如
str.append("1.23456789086756 ; ")? -
我猜你想把它写到文件或其他东西中。如果是这样,只需创建一个流并将值写入流。它只会将值附加到当前流位置,您不必担心 str.append。如果这是最终计算的一部分,您可能还会发现将 * 替换为 + 会更快 - 尽管现在不确定,但必须对其进行测试
-
似乎有问题的部分是从
Double到String的转换,其他一切在我的测试中都非常快。
标签: swift string optimization concatenation