[解決済み】.NETで文字列が不変なら、なぜSubstringはO(n)時間かかるの?
質問
.NETでは文字列は不変であるのに、なぜ
string.Substring()
はO(
substring.Length
) の時間ではなく
O(1)
?
つまり、トレードオフがあるとすれば、それは何だったのでしょうか?
解決方法は?
UPDATE: この質問がとても気に入ったので、ブログに書きました。参照 文字列、不変性、永続性
簡単に言うと O(n)は、nが大きくならなければO(1)です。 ほとんどの人は小さな文字列から小さな部分文字列を取り出すので、漸近的にどのように複雑さが増していくかは 全く関係ない .
長くなりましたが、その答えは
インスタンスに対する操作によって、わずかな量(通常 O(1) または O(lg n))のコピーまたは新規割り当てで元のメモリを再利用できるように構築された不変データ構造を、quot; persistent" immutable data structure と呼びます。.NETの文字列は不変ですが、ご質問は本質的に「なぜ永続的でないのですか?
という操作に注目すると 通常 .NETプログラムで文字列に対して行われることは、あらゆる関連する方法で ほとんど悪化しない は、単に全く新しい文字列を作成することです。 複雑な永続的データ構造を構築するための費用と難易度は、それ自体ではペイしないのです。
通常、quot;substring"は、ある程度長い文字列(数百文字程度)の中から、短い文字列(例えば10文字や20文字)を取り出すために使用されます。カンマで区切られたファイルのテキスト行があり、3番目のフィールドである姓を抽出したいとします。行の長さは数百文字で、名前は数十文字です。文字列の割り当てと50バイトのメモリコピーは 驚異的な速さ 最近のハードウェアでは 既存の文字列の中央へのポインタと長さからなる新しいデータ構造を作ることは また 驚くほど速いというのは関係なく、「十分速い」というのは定義上、十分速いということです。
抽出された部分文字列は通常サイズが小さく、寿命も短いです。ガベージコレクタはすぐにそれらを回収するつもりですし、そもそもヒープ上でそれほど場所を取っていません。つまり、メモリの大部分を再利用するような永続的な戦略をとることも、得策ではありません。ガベージコレクタが内部ポインタの処理に悩まされるようになり、遅くなるばかりです。
もし、文字列に対して通常行われる部分文字列操作がまったく異なるものであれば、永続的なアプローチを取ることは理にかなっていると言えるでしょう。もし、一般的に100万文字の文字列があり、何千もの重複する10万文字単位の部分文字列を抽出し、それらの部分文字列がヒープ上で長い間生きているとしたら、持続的部分文字列アプローチを採用することは完全に理にかなっていると言えるでしょう。しかし ほとんどのビジネスプログラマーは、そのようなことを漠然としたものでさえしません。 . DNA解析のプログラマーは、このような文字列の使用特性を持つ問題を毎日解決しなければなりませんが、あなたはそうではない可能性が高いです。DNA解析のプログラマーは、このような文字列の使用特性を持つ問題を毎日解決しなければなりません。 その を使用するシナリオがあります。
例えば、私のチームでは、C#やVBのコードを入力すると、その場で解析するプログラムを書いています。これらのコードファイルの一部は 巨大 そのため、部分文字列の抽出や文字の挿入・削除などの文字列操作をO(n)で行うわけにはいきません。私たちは、テキストバッファの編集を表現するための永続的で不変のデータ構造を構築し、既存の文字列データの大部分を迅速かつ効率的に再利用することを可能にしました。 と 既存の字句解析や構文解析が、典型的な編集の際に行われます。これは解決困難な問題で、その解決方法はC#とVBのコード編集という特殊な分野に特化したものであった。組み込みの文字列型にこの問題を解決することを期待するのは非現実的でしょう。
関連
-
[解決済み】「The breakpoint will not currently be hit」を改善するには?このドキュメントにはシンボルが読み込まれていません。" という警告はどうすれば改善されますか?
-
[解決済み】Unity 「関連するスクリプトを読み込むことができません」「Win32Exception: システムは指定されたファイルを見つけることができません"
-
[解決済み] ランダムな文字列を使用するこのコードは、なぜ "hello world" と表示されるのですか?
-
[解決済み] C#がforeachで変数を再利用するのは理由があるのか?
-
[解決済み] なぜList<T>を継承しないのですか?
-
[解決済み] Pythonスクリプトのプロファイリングはどのように行うのですか?
-
[解決済み] と'is'のどちらかを使って文字列を比較すると、異なる結果になることがあるのはなぜですか?
-
[解決済み] DateTimeとDateTimeOffsetの比較
-
[解決済み】大文字・小文字を区別しない「Contains(string)
-
[解決済み】文字列の中にある文字列(実際はchar)の出現回数を数えるには?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】C#におけるtypedefの等価性
-
[解決済み】Excel "外部テーブルが期待された形式ではありません。"
-
[解決済み】プロジェクトビルド時のエラー。エディタでスクリプトにコンパイルエラーがあるため、Playerのビルドにエラーが発生する
-
[解決済み] [Solved] 不正な文字列値: '\xEFxBFxBD' for column
-
[解決済み】EF 5 Enable-Migrations : アセンブリにコンテキストタイプが見つかりませんでした
-
[解決済み] EntityTypeにキーが定義されていないエラー
-
[解決済み】Moqを使用してメソッド呼び出しを検証する
-
[解決済み】Linq 構文 - 複数列の選択
-
[解決済み] ...基礎となる接続は閉じられました。予期しないエラーが受信で発生しました
-
[解決済み】画像のペイントにTextureBrushを使用する方法