当swift使用String.count
时:
O(n)每当我们调用它时,我们遍历整个String以计算它
或
O(1)其中swift先前已存储此数组的大小并只是访问它。
答案 0 :(得分:2)
绝对是O(n)
。来自Swift Book:
因此,如果不迭代字符串以确定其扩展的字形集群边界,则无法计算字符串中的字符数。如果您使用特别长的字符串值,请注意
count
属性必须遍历整个字符串中的Unicode标量,以确定该字符串的字符。
这有一些影响,其中最大的一个是整数下标(即str[5]
)无法通过标准库获得。在内部,String
使用ASCII或UTF-16编码(这可能随时改变)。如果字符串仅使用ASCII字符,则count
可以是O(1)
,但ASCII只有127个字符,因此请将此视为异常,而不是规则。
NSString
始终使用UTF-16,因此访问其length
为O(1)
。并且还要记住NSString.length != String.count
(尝试使用表情符号,你会看到)。
至于你的第二个问题,它不会为后续调用缓存count
。因此,count
的每次调用都是O(n)
,即使字符串没有更改。 Foundation回购中的代码也证实了这一点。
答案 1 :(得分:1)
在找不到相关文档或能够在源代码中找到此函数后,我自己使用如下所述的性能测试对此进行了测试。假设基于PHP's Array为O(1)的O(1)是可能的。 Swifts String.count
函数似乎是 O(n)。
<强>结果
现在之前调用count
时会缓存吗? (无)强>
我还测试过,看一次调用String.count
是否会缓存它。通过比较已经调用count
的时间以及将其存储到变量中的结果,以确保在我们的正常测试中调用.count
之前没有存储它。
<强>测试强>
import XCTest
class CountTests: XCTestCase {
func test100K() {
let testString = String(repeating: "a", count: 100000)
self.measure {
_ = testString.count
}
}
func test1000K() {
let testString = String(repeating: "a", count: 1000000)
self.measure {
_ = testString.count
}
}
func test10000K() {
let testString = String(repeating: "a", count: 10000000)
self.measure {
_ = testString.count
}
}
func test10000KCached() {
let testString = String(repeating: "a", count: 10000000)
_ = testString.count
self.measure {
_ = testString.count
}
}
func test10000KStrong() {
let testString = String(repeating: "a", count: 10000000)
let count = testString.count
self.measure {
_ = count
}
}
}
答案 2 :(得分:-1)
基于快速的游乐场测试看起来像O(n)。
for step in 1...10 {
let length = step * 100000
let string = String(repeating: "x", count: length)
let start = Date()
let stringLength = string.count
let end = Date()
print("Length: \(stringLength), time: \(end.timeIntervalSince(start))")
}
// Length: 100000, time: 0.00178205966949463
// Length: 200000, time: 0.00132298469543457
// Length: 300000, time: 0.00184988975524902
// Length: 400000, time: 0.00218689441680908
// Length: 500000, time: 0.00302803516387939
// Length: 600000, time: 0.00368499755859375
// Length: 700000, time: 0.0039069652557373
// Length: 800000, time: 0.00444602966308594
// Length: 900000, time: 0.0052180290222168
// Length: 1000000, time: 0.00539696216583252