swift - Swift 中字符串操作的复杂性

标签 swift string utf-8 time-complexity swift3

我有 print() 风格的函数,它接受一个字符串数组并将这些字符串的 utf8 表示形式连接到 utf8 字符数组。因此,我需要估算数组的大小以对其进行预分配。

问题是:

1) 在字符串上创建不同 View 的复杂性是什么? (string.characters, string.utf8).

2) 构建 View 后,对这些 View 中的实体进行计数的复杂性是多少? (string.characters.count, string.utf8.count)

哪个更快:求和 string.utf8.count-s 或 string.characters.count * 4?我知道并非每个字符都是 4 个字节,但对于近似输出数组大小来说,这可能已经足够了。

UPD:一些基准:

let s = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."

for _ in 0...1000000 { c += s.characters.count }
for _ in 0...1000000 { c += s.utf8.count }
for _ in 0...1000000 { c += s.utf16.count }

s.characters.count: 5.55736202001572 seconds.
s.unicodeScalars.count: 2.87764900922775 seconds.
s.utf8.count: 0.901157021522522 seconds.
s.utf16.count: 0.214971005916595 seconds.

Unicode 字符串:

let s = "☁ ☂ ☃ ☄ ★ ☆ ☇ ☈ ☉ ☊ ☋ ☌ ☍ ☎ ☏ ☐ ☑ ☒ ☓ ☚ ☛ ☜ ☝ ☞ ☟☠ ☡ ☢ ☣ ☤ ☥ ☦ ☧ ☨ ☩ ☪ ☫ ☬ ☭ ☮ ☯ ☰ ☱ ☲ ☳ ☴ ☵ ☶ ☷ ☸ ☹ ☺ ☻ ☼ ☽ ☾ ☿ ♀ ♁ ♂ ♃ ♄ ♅ ♆ ♇ ♈ ♉ ♊ ♋ ♌ ♍ ♎ ♏ ♐ ♑ ♒ ♓ ♔ ♕ ♖ ♗ ♘ ♙ ♚ ♛ ♜ ♝ ♞ ♟ ♠ ♡ ♢ ♣ ♤ ♥ ♦ ♧ ♨ ♩ ♪ ♫ ♬ ♭ ♮ ♯"

s.characters.count: 9.24248600006104 seconds.
s.unicodeScalars.count: 4.10243701934814 seconds.
s.utf8.count: 2.78127604722977 seconds.
s.utf16.count: 0.210725963115692 seconds.

更长的 unicode 字符串:

let s = "Lorem ipsum dolor sit amet Лорем ипсум долор сит амет 123456789 🇯🇵 🇰🇷 🇩🇪 🇨🇳 🇺🇸 🇫🇷 🇪🇸 🇮🇹 🇷🇺 🇬🇧 😄 😃 😀 😊 ☺ 😉 😍 😘 😚 😗 😙 😜 😝 😛 😳 😁 😔 😌 😒 😞 😣 😢 😂 😭 😪 😥 😰 😅 😓 😩 😫 😨 😱 😠 😡 😤 😖 😆 😋 😷 😎 😴 😵 😲 😟 😦 😧 😈 👿 😮 😬 😐 😕 😯 😶 😇 😏 😑 👲 👳 👮 👷 💂 👶 👦 👧 👨 👩 👴 👵 👱 👼 👸☁ ☂ ☃ ☄ ★ ☆ ☇ ☈ ☉ ☊ ☋ ☌ ☍ ☎ ☏ ☐ ☑ ☒ ☓ ☚ ☛ ☜ ☝ ☞ ☟☠ ☡ ☢ ☣ ☤ ☥ ☦ ☧ ☨ ☩ ☪ ☫ ☬ ☭ ☮ ☯ ☰ ☱ ☲ ☳ ☴ ☵ ☶ ☷ ☸ ☹ ☺ ☻ ☼ ☽ ☾ ☿ ♀ ♁ ♂ ♃ ♄ ♅ ♆ ♇ ♈ ♉ ♊ ♋ ♌ ♍ ♎ ♏ ♐ ♑ ♒ ♓ ♔ ♕ ♖ ♗ ♘ ♙ ♚ ♛ ♜ ♝ ♞ ♟ ♠ ♡ ♢ ♣ ♤ ♥ ♦ ♧ ♨ ♩ ♪ ♫ ♬ ♭ ♮ ♯"

s.characters.count: 21.852580010891 seconds.
s.unicodeScalars.count: 9.216412961483 seconds.
s.utf8.count: 7.34296900033951 seconds.
s.utf16.count: 0.21273398399353 seconds.

我还在大型数据集上进行了测试(s * 100000 次)- s.utf16.count 保持相同的性能。

因此,似乎只有 s.utf16.count 是 O(1)。其他是 O(n),其中 characters 是最慢的一个。

最佳答案

无需预分配。你可以做类似的事情(大约 - 在我的手机上,无法检查语法)

Array(stringArray.joinWithSeparator("").characters.utf8)

我不确定从单个字符获取 UTF8 的语法 - 如果您不这样做,这将是一个“字符”数组。如果您停止转换为 Array,则这是一个序列。

要回答您的问题,字符串本身是 UTF16,而 astring.characters.count 非常快。如果可能存在任何多字素字符,请注意您的计数。

关于swift - Swift 中字符串操作的复杂性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38478888/

相关文章:

c++ - 将字符串移动到 vector 中

java - 如何在 Android 9 上保持 UTF-8 的向后兼容性?

swift - 从 UIDatepicker 获取日期组件

Swift 可用性条件主要版本号

ios - NSInternalInconsistencyException tableView 行删除

php - 而不是 mb_strtolower()?

objective-c - 无法使用 'schema' 类型的参数列表调用 '(String)'

c - c语言获取和检查字符串

java - 即使正确设置编码后,也无法在 mysql 中插入 CAFÉ

csv - 下载 CSV 文件 (UTF 8) 编码 ServiceStack