哪个性能更高:replaceOccurrences或components(separatedBy :)。joined()

时间:2019-05-07 08:46:27

标签: ios swift

我希望删除s String中的所有中间空格。

选项1:

 func removingWhitespaces() -> String {
    return replacingOccurrences(of: " ", with: "")
 }

选项2:

 func removingWhitespaces() -> String {
    return components(separatedBy: .whitespaces).joined()
 }

哪个表现更好?

5 个答案:

答案 0 :(得分:1)

根据我的观点,我认为选项1比选项2快。

原因:

在选项2中,您将components(separatedBy:)的返回值链接到joined()。因此最终使用了join()`的返回值,而在选项1中,您直接调用了String的内置函数。

答案 1 :(得分:1)

根据我的理解,我建议选项1

因为,

replacingOccurrences(of: " ", with: "")

仅执行一次操作。

其中

components(separatedBy: .whitespaces).joined()

将执行两次操作,并花费更多时间。首先,它将使用空格分隔元素并创建数组,然后在数组上执行 join 操作并提供输出。

答案 2 :(得分:1)

自己弄清楚。在Xcode中,基本性能测试非常简单。在XCTestCase类中,运行这两个测试

func testPerformance1() {
    let string = "I wish to remove all intermediate spaces in a String"
    self.measure {
        for _ in 0..<10000 {
            _ = string.replacingOccurrences(of: " ", with: "")
        }
    }
}

func testPerformance2() {
    let string = "I wish to remove all intermediate spaces in a String"
    self.measure {
        for _ in 0..<10000 {
            _ = string.components(separatedBy: .whitespaces).joined()
        }
    }
}

,然后在控制台中读取结果。 replacingOccurrences更快。

components(separatedBy: " ")components(separatedBy: .whitespaces)之间没有太大区别

答案 3 :(得分:0)

Splitjoined配合使用会更快,另外两个选项

sh './setup-target'

答案 4 :(得分:0)

空格

在谈到性能时,应该考虑空间的复杂性。这个术语的意思是运行这段代码需要多少内存,并描述了输入中的元素数与保留的内存之间的关系。例如,我们谈论:

    当保留内存随着输入中元素数量的增长而增加
  • O( n )空间复杂度。
  • 输入元素的数量增加时保留内存不增加时,
  • O( 1 )空间复杂度。

replacingOccurrences(of: " ", with: "")components(separatedBy: .whitespaces).joined()之间,前者在空间复杂度上取胜,因为后者创建了一个中间数组,而在 performance 中,更多

时间

给出此字符串:

let str = "Lorem ipsum dolor sit amet, tempor nulla integer morbi, amet non amet pede quis enim, ipsum in a in congue etiam, aenean orci wisi, habitant ipsum magna auctor quo odio leo. Urna nunc. Semper mauris felis vivamus dictumst. Tortor volutpat fringilla sed, lorem dui bibendum ligula faucibus massa, dis metus volutpat nec ridiculus, ac vel vitae. At pellentesque, at sed, fringilla erat, justo eu at porttitor vestibulum hac, morbi in etiam sed nam. Elit consectetuer lorem feugiat, ante turpis elit et pellentesque erat nec, vitae a fermentum vivamus ut. Orci donec nulla justo non id quis, ante vestibulum nec, volutpat a egestas pretium aliquam non sed, eget vivamus vestibulum, ornare sed tempus. Suscipit laoreet vivamus congue, tempor amet erat nulla, nostrum justo, wisi cras ac tempor tincidunt eu, hac faucibus convallis. Ac massa aenean nunc est orci, erat facilisis. Aliquam donec. Ut blandit potenti quam quis pellentesque, cursus imperdiet morbi ea ut, non mauris consectetuer mauris risus vehicula in, sed rutrum pellentesque turpis. Eros gravida volutpat justo proin donec penatibus, suspendisse fermentum sed proin fringilla libero malesuada, nulla lectus ligula, aliquam amet, nemo quis est. Quis imperdiet, class leo, lobortis etiam volutpat lacus wisi. Vestibulum vitae, nibh sem molestie natoque. Elementum ornare, rutrum quisque ultrices odio mauris condimentum et, auctor elementum erat ultrices. Ex gravida libero molestie facilisi rutrum, wisi quam penatibus, dignissim elementum elit mi, mauris est elit convallis. Non etiam mauris pretium id, tempus neque magna, tincidunt odio metus habitasse in maecenas nonummy. Suspendisse eget neque, pretium fermentum elementum."

下面给出了基准代码。每个代码块将单独运行,而其他代码块将被注释掉。 :

do {
    let start = Date()
    let result = str.components(separatedBy: " ").joined()
    let end = Date()
    print(result.count, end.timeIntervalSince(start))
}

do {
    let start = Date()
    let result = str.split(separator: " ").joined()
    let end = Date()
    print(result.count, end.timeIntervalSince(start))
}

do {
    let start = Date()
    let result = str.filter { !$0.isWhitespace }
    let end = Date()
    print(s.count, end.timeIntervalSince(start))
}

do {
    let start = Date()
    var s = str
    s.removeAll { $0.isWhitespace }
    let end = Date()
    print(s.count, end.timeIntervalSince(start))
}

do {
    let start = Date()
    let result = str.components(separatedBy: .whitespaces).joined()
    let end = Date()
    print(result.count, end.timeIntervalSince(start))
}

do {
    let start = Date()
    var result = ""

    for char in str where char != " " {
        result.append(char)
    }

    let end = Date()
    print(result.count, end.timeIntervalSince(start))
}

do {
    let start = Date()
    let result = str.replacingOccurrences(of: " ", with: "")
    let end = Date()
    print(result.count, end.timeIntervalSince(start))
}

do {
    let start = Date()
    var arr = str.utf8CString
    arr.removeAll(where: { $0 != 32 })
    var result = ""
    arr.withUnsafeBufferPointer { ptr in
        result = String(cString: ptr.baseAddress!)
    }
    let end = Date()
    print(result.count, end.timeIntervalSince(start))
}

使用以下命令在终端中进行了优化编译:

xcrun swiftc -O ReplaceStr.swift -o replaceStr
  • -O:经过优化
  • ReplaceStr.swift:包含代码的文件的名称。您应该先cd到该文件的位置。
  • -o:指定输出编译文件的名称
  • replaceStr是输出文件的示例名称

然后使用./replaceStr

运行

多次运行每个块之后,以下是最佳时间:

components(separatedBy: " ").joined()          : 0.77ms
components(separatedBy: .whitespaces).joined() : 0.75ms
str.split(separator: " ").joined()             : 0.54ms
filter { !$0.isWhitespace }                    : 0.52ms
removeAll { $0.isWhitespace }                  : 0.52ms
for char in str where char != " "              : 0.26ms
replacingOccurrences(of: " ", with: "")        : 0.23ms
str.utf8CString                                : 0.18ms

使用较短的字符串发现了可比较的结果:

let str = "Lorem ipsum dolor sit amet, tempor nulla integer morbi, amet non amet pede quis enim, ipsum in a in congue etiam, aenean orci wisi, habitant ipsum magna auctor quo odio leo."

判决

replacingOccurrences(of: " ", with: "")在时间复杂度上也优于components(separatedBy: .whitespaces).joined()。部分原因是replacingOccurrences(of:with:)是在NSString而不是String上定义的。从某种意义上说,这就像与进行比较。

处理基础CString可以击败所有问题,并且总体上是最好的。


有关基准测试代码的更多信息,这是一个不错的thread