在swift中非常快速地添加字符串
下面的代码显示了构建电子表格的两种方法: 通过使用:在swift中非常快速地添加字符串,swift,string,optimization,concatenation,Swift,String,Optimization,Concatenation,下面的代码显示了构建电子表格的两种方法: 通过使用: str = str + "\(number) ; " 或 这两个都非常慢,因为我认为,它们丢弃了两个字符串,生成了第三个字符串,这是前两个字符串的串联。 现在,如果我重复这个操作数十万次来生成一个电子表格。。。这导致了大量的分配 例如,在我的MacBook Pro 2016上执行以下代码需要11秒: let start = Date() var str = ""; for i in 0 ..< 86400
str = str + "\(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);
但是编译器告诉我:
Variable 'str' was never mutated; consider changing to 'let' constant
尽管
str.append("\(Double(j) * 1.23456789086756 + Double(i)) ; ");
显然,调用append不会改变字符串…我尝试将其写入数组,限制因素似乎是将double转换为字符串 下面的代码在我的广播中大约需要13秒 这样做
arr[i][j] = "1.23456789086756"
将执行时间降低到2秒,因此将Double转换为String需要11秒。通过编写自己的转换例程,您可能可以节省一些时间,但这似乎是一个限制因素。我尝试过使用内存流,但速度似乎更慢
var start = Date()
var arr = Array(repeating: Array(repeating: "1.23456789086756", count: 80), count: 86400 )
var duration = Date().timeIntervalSinceReferenceDate - start.timeIntervalSinceReferenceDate;
print(duration); //0.007
start = Date()
var a = 1.23456789086756
for i in 0 ..< 86400
{
for j in 0 ..< 80
{
arr[i][j] = "\(a)" // "1.23456789086756" //String(a)
}
}
duration = Date().timeIntervalSinceReferenceDate - start.timeIntervalSinceReferenceDate;
print(duration); //13.46 or 2.3 with the string
var start=Date()
var arr=数组(重复:数组(重复:“1.23456789086756”,计数:80),计数:86400)
var duration=Date().TimeIntervalnceReferenceDate-start.TimeIntervalnceReferenceDate;
打印(持续时间)//0.007
开始=日期()
变量a=1.23456789086756
对于0..<86400中的i
{
对于0..<80的j
{
arr[i][j]=“\(a)”/“1.23456789086756//String(a)
}
}
duration=Date().TimeIntervalsIncerenceDate-start.TimeIntervalsIncerenceDate;
打印(持续时间)//13.46或2.3与字符串
我尝试将其写入数组,但限制因素似乎是将double转换为字符串
下面的代码在我的广播中大约需要13秒
这样做
arr[i][j] = "1.23456789086756"
将执行时间降低到2秒,因此将Double转换为String需要11秒。通过编写自己的转换例程,您可能可以节省一些时间,但这似乎是一个限制因素。我尝试过使用内存流,但速度似乎更慢
var start = Date()
var arr = Array(repeating: Array(repeating: "1.23456789086756", count: 80), count: 86400 )
var duration = Date().timeIntervalSinceReferenceDate - start.timeIntervalSinceReferenceDate;
print(duration); //0.007
start = Date()
var a = 1.23456789086756
for i in 0 ..< 86400
{
for j in 0 ..< 80
{
arr[i][j] = "\(a)" // "1.23456789086756" //String(a)
}
}
duration = Date().timeIntervalSinceReferenceDate - start.timeIntervalSinceReferenceDate;
print(duration); //13.46 or 2.3 with the string
var start=Date()
var arr=数组(重复:数组(重复:“1.23456789086756”,计数:80),计数:86400)
var duration=Date().TimeIntervalnceReferenceDate-start.TimeIntervalnceReferenceDate;
打印(持续时间)//0.007
开始=日期()
变量a=1.23456789086756
对于0..<86400中的i
{
对于0..<80的j
{
arr[i][j]=“\(a)”/“1.23456789086756//String(a)
}
}
duration=Date().TimeIntervalsIncerenceDate-start.TimeIntervalsIncerenceDate;
打印(持续时间)//13.46或2.3与字符串
我不认为str.append
或Double
很慢。。。调用一行嵌套代码86400*80=6912000次会让任何事情看起来都很慢。是的,我知道。这是因为我让6912000根绳子成长。。。所以我复制,分配,等等。。。移除该部分(无需添加,只需创建一个新字符串)并查看其运行速度(0.043秒)。分配是这里的杀手。所以我试着让它成为一个有容量的NSMutableString,但很明显,在swift3中,附加副本而不是变异。启用优化后,“不添加,只创建一个新字符串”代码将被删除。您的代码附加常量字符串需要多少时间,比如str.append(“1.23456789086756;”)
?我猜您想将其写入文件或其他文件。如果是这样,只需创建一个流并将值写入流即可。它只会将值附加到当前流位置,您不必担心str.append。如果这是最终计算的一部分,您可能会发现用+替换*会更快-虽然现在还不确定,但必须测试它。问题似乎在于从双精度
到字符串的转换,在我的测试中,其他一切都很快。我不认为str.append
或Double
很慢。。。调用一行嵌套代码86400*80=6912000次会让任何事情看起来都很慢。是的,我知道。这是因为我让6912000根绳子成长。。。所以我复制,分配,等等。。。移除该部分(无需添加,只需创建一个新字符串)并查看其运行速度(0.043秒)。分配是这里的杀手。所以我试着让它成为一个有容量的NSMutableString,但很明显,在swift3中,附加副本而不是变异。启用优化后,“不添加,只创建一个新字符串”代码将被删除。您的代码附加常量字符串需要多少时间,比如str.append(“1.23456789086756;”)
?我猜您想将其写入文件或其他文件。如果是这样,只需创建一个流并将值写入流即可。它只会将值附加到当前流位置,您不必担心str.append。如果这是最终计算的一部分,您可能会发现用+替换*会更快-虽然现在还不确定,但必须测试它。问题似乎在于从双精度
转换为字符串
,其他一切在我的测试中都非常快。+1–谢谢,即使我没有尝试填充数组。我会再等一会儿,如果没有更多的答复,我会接受你的回答,因为这是最接近问题的答案。@Adeline一种精简的方法是将常规并行化-可能很明显,但只是以防万一,在这种情况下做起来很简单。如果你有一个四核,你可以期待得到它下降到几秒钟+1–谢谢,即使我不试图填补阵列。我会再等一会儿,如果没有更多的答复,我会接受你的回答,因为这是最接近这个问题的答案。@Adeline一种精简它的方法是将常规并行化-可能很明显,但我刚才提到过