問題タブ [string-interning]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票する
1 に答える
952 参照

java - ハッシュマップKey で String.intern() を使用して同期された .remove() は機能しますか? それとも、これは壊れたコードですか?

私は最近、次の構造に出くわしました

intern()通常はそれほど高速ではないことを考えると、これがsynchronized, Collections.synchronizedMap(Map)orを使用した場合よりも優れているとは思えませんConcurrentHashMap。しかし、この特定のケースでは、この構造が他のすべての方法よりも高速であったとしても、これは適切に同期されていますか? ハッシュテーブルの再編成中に削除が発生する可能性があるため、これがスレッドセーフであるとは思えません。しかし、これがうまくいくとしても、HashMap javadocが次のように述べていることを考えると、コードが壊れているのではないかと思います。

複数のスレッドが同時にハッシュ マップにアクセスし、少なくとも 1 つのスレッドがマップを構造的に変更する場合は、外部で同期する必要があります。

0 投票する
3 に答える
91 参照

c# - パフォーマンス - str_01 == str_02 vs (オブジェクト)str_01 == (オブジェクト)str_02

2 つの文字列を比較する以下のコード サンプルで、パフォーマンスの最適化はありますか?

初め:

二:

両方とも戻るtrue

彼らのilコードには1つだけ違いがあります:

1位:

2番目:

System.Stringで次のようなものを見つけました:

0 投票する
4 に答える
384 参照

c# - 文字列ポインタの位置が異なるのはなぜですか?

アプリケーションを実行するたびに文字列ポインターの位置が異なるのはなぜStringBuilderですか?

出力:

40907812
178488268

次の時間:

40907812
179023248

次の時間:

40907812
178448964

0 投票する
3 に答える
1627 参照

c# - 文字列のインターンと代替について

本質的に次のようなデータを含む大きなファイルがあります。

これは数ギガバイトのファイルです。このファイルを読み取り、これらの行 (レコード) をIEnumerable<MyObject>. これMyObjectには、いくつかのプロパティ ( CountryProvinceCity、...) などがあります。

ご覧のとおり、データの重複がたくさんあります。基になるデータを として公開し続けたいと思いIEnumerable<MyObject>ます。ただし、他のクラスでは、次のようなこのデータの階層ビュー/構造を作成する可能性があります (おそらくそうするでしょう)。

このファイルを読むときは、基本的に次のようにします。

さて、手元にある実際の質問に: Country、Province、City、Street の文字列をインターンするために使用できます (これらは主な「悪役」であり、質問に関係のない他のいくつかのプロパティがあります)。string.Intern()MyObject

これにより、すべての重複文字列が同じ文字列への参照になるため、データセット全体をメモリに保持すると、約 42% のメモリ (テストおよび測定) が節約されます。また、多くの LINQ の.ToDictionary()メソッドで階層構造を作成する場合、それぞれのキー (Country、Province など) を使用します。辞書ははるかに効率的になります。

ただし、使用の欠点の 1 つ (問題ではないパフォーマンスのわずかな損失は別として) はstring.Intern()、文字列がガベージ コレクションされなくなることです。しかし、データの処理が終わったら、(最終的には) ガベージをすべて収集したいと思います

を使用してこのデータを「インターン」することもできDictionary<string, string>ますが、 を使用することの「オーバーヘッド」が好きではなくkeyvalue実際には にのみ関心がありkeyます。を設定valueするnullか、値として同じ文字列を使用することができます (結果として と で同じ参照にkeyなりvalueます)。支払うのは数バイトのわずかな代償ですが、それでも代償です。

のようなものは、HashSet<string>私にとってより理にかなっています。ただし、HashSet 内の文字列への参照を取得できません。HashSet に特定の文字列が含まれているかどうかはわかりますが、HashSet 内にある文字列の特定のインスタンスへの参照は取得できません。私はこれのために自分自身を実装することができHashSetましたが、あなたが種類の StackOverflowers を思い付くことができる他の解決策を考えています.

要件:

  • 私の「FileReader」クラスは、IEnumerable<MyObject>
  • 私の「FileReader」クラスは、メモリ使用量を最適化するために(のような)ことをするかもしれませんstring.Intern()
  • MyObjectクラスは変更できません。Cityクラス、Countryクラスなどを作成せず、それらを単純なプロパティMyObjectではなくプロパティとして公開しますstring
  • Country目標は、ProvinceCityなどの重複文字列のほとんどを重複排除することにより、(より) メモリ効率を高めることです。これがどのように達成されるか (例: 文字列インターン、内部ハッシュセット / コレクション / 何かの構造) は重要ではありません。でも:
  • データベースにデータを詰め込むか、そのような方向で他のソリューションを使用できることを知っています。この種のソリューションには興味がありません。
  • 速度は二次的な問題にすぎません。もちろん、速ければ速いほど良いですが、オブジェクトの読み取り/反復中のパフォーマンスの(わずかな)低下は問題ありません
  • これは長時間実行されるプロセス (例: 24 時間 365 日実行されている Windows サービス) であるため、時折、このデータの大量を処理します。文字列インターニングはうまく機能しますが、長期的には、未使用のデータがたくさんある巨大な文字列プールになります
  • 解決策は「シンプル」にしたいと思います。P/Invokes とインライン アセンブリ (誇張されています) を使用して 15 個のクラスを追加することは、努力する価値がありません。コードの保守性は私のリストの上位にあります。

これは「理論的な」質問です。私が尋ねているのは純粋に好奇心/興味からです. 「本当の」問題はありませんが、同様の状況でこれが誰かの問題になる可能性があることがわかります。


例: 次のようなことができます。

しかし、(重複除去する) 文字列のセットが大きいと、これはすぐに行き詰まります。HashSetまたはDictionaryまたは ...の参照ソースをのぞいて、メソッドの bool を返さずAdd()、内部/バケットで見つかった実際の文字列を返す同様のクラスを構築できます。

今まで思いついた最高のものは次のようなものです:

これには、実際にはキーのみに関心があるキー値を持つという「ペナルティ」があります。ほんの数バイトですが、支払う代償はわずかです。偶然にも、これによりメモリ使用量も 42% 減少します。string.Intern()yieldsを使用した場合と同じ結果になります。

tolanj は System.Xml.NameTable を思いつきました:

(ロックとstring.Emptyチェックを削除しました(後者はNameTableがすでにそれを行っているためです))

xanatos は CachingEqualityComparer を思いつきました:

(私の「Add()インターフェース」に「フィット」するようにわずかに変更されました)

Henk Holterman のリクエストによると:

私の(実際の多くではない)問題を「解決」するための、よりきちんとした/より良い/よりクールな方法があるかどうか疑問に思っています。今では十分な選択肢があると思いますウィンク


以下は、単純で短い予備テストのために私が思いついたいくつかの数値です。


最適化され
ていないメモリ: ~4,5Gb
読み込み時間: ~52秒


StringInterningObject (上記のConcurrentDictionaryバリアントを参照)
メモリ: ~2,6Gb
読み込み時間: ~49 秒


string.Intern()
メモリ: ~2,3Gb
読み込み時間: ~45 秒


System.Xml.NameTable
メモリ: ~2,3Gb
読み込み時間: ~41 秒


CachingEqualityComparer
メモリ: ~2,3Gb
読み込み時間: ~58 秒


Henk Holterman の要求によるStringInterningObject (上記の (非並行)Dictionaryバリアントを参照) :メモリ: ~2,3Gb読み込み時間: ~39 秒

数値はあまり決定的なものではありませんが、最適化されていないバージョンの多くのメモリ割り当ては、実際にはどちらかstring.Intern()または上記StringInterningObjectの s を使用するよりも遅くなり、ロード時間が (わずかに) 長くなるようです。また、string.Intern()「勝つ」ように見えStringInterningObjectますが、大差ではありません。<< 更新を参照してください。

0 投票する
1 に答える
52 参照

clr - インターンプールを利用するのはどれですか?

編集: この MSDN ページの備考を見る

https://msdn.microsoft.com/en-us/library/system.string.intern(v=vs.110).aspx

String.Intern については、CLR がリテラル文字列およびインターン プールと対話する方法について言及しています。

文字列リテラル以外のインターンプールへの参照を追加する他の例があるかどうか疑問に思っていましたか?

すべてが抑留されているものの明示的なリストを見つけることはできますか?