Swift的字符串处理效率问题

在使用swift原生api对字符串进行处理时,发现其处理效率特别低。经过测试对比发现,处理大量数据时,相同长度的数组和字符串,数组的处理能力可以达到字符串的几十倍。测试代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
func testStringCount() {
let string = String(Array(repeating: "a", count: 1000))
print(111, Date.now.timeIntervalSince1970)
var a = 0
for _ in 0 ..< 100000 {
a = string.count
}
print(222, Date.now.timeIntervalSince1970)
}

func testArrayCount() {
let array = Array(repeating: "a", count: 1000)
print(333, Date.now.timeIntervalSince1970)
var a = 0
for _ in 0 ..< 100000 {
a = array.count
}
print(444, Date.now.timeIntervalSince1970)
}

打印结果如下:

1
2
3
4
111 1588738767.130898
222 1588738769.177166
333 1588738769.17723
444 1588738769.260538

所以,在字符串内容较多或需要处理大量字符串时,把字符串转换成Array来处理,效率会更高。比如:

  • 获取字符串长度

    1
    2
    3
    4
    5
    6
    let str = "0123456789" 

    // 获取字符串长度
    print(str.count) // 慢
    let arr = Array(str)
    print(arr.count) // 快
  • 获取某个下标的子字符串

    1
    2
    3
    4
    let str = "0123456789" 
    let index = 3
    let sub1 = String(str[str.index(str.startIndex, offsetBy: index)])
    let sub2 = String(arr[index]) //快
  • 获取某个范围的子串(方法3的效率最高)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    let s = String(Array(repeating: "a", count: 1000))
    let left = 100
    let right = 123

    // 方法1
    let start = s.index(s.startIndex, offsetBy: left)
    let end = s.index(s.startIndex, offsetBy: right)
    let sub1 = String(s[start..<end])

    // 方法2
    let arr = s.map({ String.init($0)})
    let sub2 = arr[left ..< right].joined()

    // 方法3
    let arr2 = Array(s)
    let sub3 = String(arr2[left ..< right])