我理解为什么Character类不支持toUpper()toLower()的原因,但是我的用例不是用于语言目的的。此外,我不想回到NSString
那么,使用Swift 4将字符转换为大写或小写的最快方法是什么?

// Is there something better than this?
extension Character {
    func toLower() -> Character {
        return String(self).lowercased().first!
    }
}

最佳答案

如果只需要大写第一个字符,请使用下面的uppercase2()。它比整个管柱的上套管速度快5倍。

import Foundation

// too slow, maybe with some bitwise operations could get faster 🤷‍♀️
func uppercase(_ string: String) -> Character? {
    let key: Int8 = string.utf8CString[0]
    guard key>0, key<127, let c = Unicode.Scalar(Int(key >= 97 ? key - Int8(32) : key)) else { return nil }
    return Character(c)
}

// winner but using internal _core stuff
func uppercase2(_ string: String) -> Character? {
    guard let key = string._core.asciiBuffer?[0] else { return nil }
    return Character(Unicode.Scalar(key >= 97 ? key - 32 : key)) // use < + to lowercase
}

func measure(times: Int, task: ()->()){
    let start1 = CFAbsoluteTimeGetCurrent()
    for _ in 1..<times {
        task()
    }
    print(CFAbsoluteTimeGetCurrent() - start1)
}

print("😀".uppercased().first as Any) // Optional("😀")
print(uppercase("😀") as Any) // nil
print(uppercase2("😀") as Any) // nil

measure(times: 10_000_000) { _ = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".uppercased().first } // 4.17883902788162
measure(times: 10_000_000) { _ = uppercase("ABCDEFGHIJKLMNOPQRSTUVWXYZ") }         // 4.91275697946548
measure(times: 10_000_000) { _ = uppercase2("ABCDEFGHIJKLMNOPQRSTUVWXYZ") }        // 0.720575034618378

在1000万次的运行中,苹果的uppercased运行速度是本文底部代码的148倍,即使使用了force unwrap。我把它留作喜剧用。
他们的方法当然要低得多。见lowercased()。他们检查内部腹水过滤器,然后使用_asciiUpperCaseTable
我的理解是,如果原始字符串已经是一个Swift字符串,那么它将由一个StringCore类来表示,该类已经被优化为在低级别处理ASCII字符。因此,您将无法击败Swift的大写函数。
所以,答案是:最快的方法是使用regularuppercase()函数。
我假设“我的用例不是用于语言目的”意味着我只使用ASCII。这样做的好处是UTF-8和ASCII共享相同的标量代码,因此大小写意味着减去或添加一个固定的数字。
import Foundation

print("a".unicodeScalars.first!.value) // 97
print("A".unicodeScalars.first!.value) // 65

let uppercase = String("abcde".flatMap {
    guard let char = $0.unicodeScalars.first,
          let uppercased = Unicode.Scalar(char.value - UInt32(97 - 65))
    else {
        return nil
    }
    return Character(uppercased)
})

print(uppercase) // ABCDE

关于swift - 在Swift 4中将Character转换为大写或小写的最快方法?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/46789566/

10-14 19:59
查看更多