2016-07-20 14 views
2

私はprint()スタイルの関数を用意しています。この関数は文字列の配列をとり、これらの文字列のutf8表現をutf8 char配列に連結します。だから、私はそれを事前に割り当てるために配列のサイズを近似する必要があります。Swiftでの文字列操作の複雑さ

質問です:

1)文字列の異なるビューを作成するための複雑さとは何ですか? (string.characters,string.utf8)。

2)ビューを作成すると、これらのビュー内のエンティティを数えるのはどのくらい複雑ですか? (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. 

さらに長いユニコード文字列:

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が最も遅いものです。

+1

なぜアレイのサイズを近似する必要がありますか? – Azzaknight

+5

すべて*「どちらが速くなるでしょうか」*質問には、自分で差異を測定した試行が少なくとも含まれている必要があります。アプリのその部分で費やされた時間がまったく関連しているかどうかを知ることもできます。 –

+0

@ martin-r合意し、ベンチマークを行い、質問を更新します。私はそれらのうちのどれがO(1)であり、どちらがO(n)であるかを知りたかった。 – Zmey

答えて

0

事前に割り当てる必要はありません。私はあなたがそれをオフのままにした場合、文字-、これは次のようになり個体からUTF8を取得するには、構文のか分からない

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

- (私の携帯電話に、構文をチェックすることはできません約)のようにあなたは何かを行うことができます'文字'の配列。配列への変換を中止した場合、これはシーケンスです。

あなたの質問に答えるために、文字列はネイティブにUTF16で、astring.characters.countは非常に高速です。複数書記文字のいずれかが存在する可能性がある場合には、何を考慮するか注意してください。

+0

docsによるCharacterは拡張された書記素クラスタを表します。内部文字列ストレージがUTF16の場合、 'astring.characters.count'はおそらく文字列全体を反復することになり、遅くなるはずです。 – Zmey

+1

いいえ、カウントは直接維持されます。迅速な店舗の文字列に関する記事は、https://www.mikeash.com/pyblog/friday-qa-2015-11-06-why-is-swifts-string-api-so-hard.html – Feldur

+0

でご覧いただけます。質問にベンチマークデータを追加したところ、すべてのビューの中で文字が最も遅いようです。 – Zmey