import UIKit
import CoreFoundation
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let a = "abscdefghi jkl¢€@sads dljlæejktæljæ leijroptjiæa Dog!🐶 iojeg r æioej rgæoija"
let b = a
timeStringAdding(a, string2: b, times: 1_000_000, repetitions: 5)
}
struct RunTimer: CustomStringConvertible {
var begin: CFAbsoluteTime
var end:CFAbsoluteTime
init() {
begin = CFAbsoluteTimeGetCurrent()
end = 0
}
mutating func start() {
begin = CFAbsoluteTimeGetCurrent()
end = 0
}
@discardableResult
mutating func stop() -> Double {
if (end == 0) { end = CFAbsoluteTimeGetCurrent() }
return Double(end - begin)
}
var duration: CFAbsoluteTime {
get {
if (end == 0) { return CFAbsoluteTimeGetCurrent() - begin }
else { return end - begin }
}
}
var description: String {
let time = duration
if (time > 100) {return " \(time/60) min"}
else if (time < 1e-6) {return " \(time*1e9) ns"}
else if (time < 1e-3) {return " \(time*1e6) µs"}
else if (time < 1) {return " \(time*1000) ms"}
else {return " \(time) s"}
}
}
func timeStringAdding(string1:String, string2:String, times:Int, repetitions:Int) {
var newString = ""
var i = 0
var j = 0
var timer = RunTimer()
while j < repetitions {
i = 0
timer.start()
while i < times {
newString = string1 + " " + string2
i += 1
}
print("+ add \(timer)")
i = 0
timer.start()
while i < times {
newString = "\(string1) \(string2)"
i += 1
}
print("\\( add \(timer)")
j += 1
}
}
}
在iPhone 6S Plus上,它给出了:
+ add 727.977991104126 ms
\( add 1.1197350025177 s
+ add 693.499982357025 ms
\( add 1.11982899904251 s
+ add 690.113961696625 ms
\( add 1.12086200714111 s
+ add 707.363963127136 ms
\( add 1.13451600074768 s
+ add 734.095990657806 ms
\( add 1.19673496484756 s
而在模拟器(iMac视网膜):
+ add 406.143009662628 ms
\( add 594.823002815247 ms
+ add 366.503953933716 ms
\( add 595.698952674866 ms
+ add 370.530009269714 ms
\( add 596.457958221436 ms
+ add 369.667053222656 ms
\( add 594.724953174591 ms
+ add 369.095981121063 ms
\( add 595.37798166275 ms
5条答案
按热度按时间lawou6xi1#
我在模拟器和iPhone6S Plus上运行了下面的代码。两种情况下的结果都显示,对于我使用的字符串,
string1 + " " + string2
加法更快。我没有尝试使用不同类型的字符串、优化等,但您可以运行代码并检查特定的字符串等。尝试在IBM Swift沙箱中在线运行此代码。计时器结构来自以下内容:在Swift中测量经过的时间要运行代码,请在Xcode中创建一个单一视图应用程序,并将以下代码添加到ViewController:
在iPhone 6S Plus上,它给出了:
而在模拟器(iMac视网膜):
大部分时间是为字符串结构体分配和释放内存,对于那些真正感兴趣的人,请运行
Instruments panel
中的代码,使用Time Profiler
,看看分配和释放等的时间是如何分配的,与机器码有关,也显示在那里。ojsjcaue2#
这个问题激起了我的好奇心,所以我把这个放进了一个新的项目。这些都是快速而肮脏的基准,应该与通常的盐粒采取,但结果是耐人寻味的。
在我的MacBook Pro(2014年中的i7,2.5GHz)上运行的模拟器上运行6次,输出到调试控制台的平均时间为1.36秒。作为调试代码部署到我的iPhone 6S上,6次运行的所有输出的平均时间为1.33秒。
使用相同的代码,但将字符串连接到的行更改为...
......给了我一个不一样的结果,模拟器上运行6次,调试台上报告的平均时间是50.86秒,iPhone 6S上运行6次,平均时间是88.82秒,这几乎是两个数量级的差距。
这些结果表明,如果必须连接大量字符串,则应使用
+
运算符,而不是字符串插值。0pizxfdo3#
最快的方法可能取决于实现。您可以对编译器、编译器优化设置、库、框架、操作系统和处理器/CPU的特定组合进行基准测试。但在不同的组合下,性能可能会有很大差异。
对于string 1和string 2是否可变,答案也可能不同,但这也取决于编译器优化级别。
33qvvth14#
雨燕3
在Swift 3中连接字符串的另一种方法是使用
joined
:当然,这要求字符串在一个数组中。我没有做过任何时间配置文件,所以不能将其与其他建议的解决方案进行比较。
zi8p0yeb5#
TL;DR:只有在处理大字符串(数百万字节/字符)时,差异才会明显。
所有测试均在iMac 21.5 Late 2012, 2.7GHz Intel Core i5上编译和执行。
我做了一个小的基准测试。下面是代码。
插值.swift用
swiftc ./interpolation.swift -o ./interpolation
编译带
-emit-assembly
标志的swiftc
的输出:addstr.swift(
+
运算符)用swiftc ./addstr.swift -o ./addstr
编译带
-emit-assembly
标志的swiftc
的输出:正如您所看到的,addstr.swift的程序集包含的命令比interpolation.swift少。
以下是使用
/usr/bin/time
进行计时的基准测试结果(bash-3.2)。我已经多次运行此测试,但结果始终相同(±0.001s)。