web-dev-qa-db-ja.com

なぜ原子/記号?

Rubyのようなプログラミング言語がシンボルを使用するのはなぜですか?文字列の操作はルックアップテーブルを使用するよりもはるかに遅いこと、および文字列が同じであるかどうかに関係なくメモリに再割り当てされるという考えを理解しています。以前に使用したものとは異なりますが、インタプリタはこれを補うことができませんか?インタプリタは、入力したWordをシンボルと照合するために解析する必要があるように思われるので、文字列オブジェクトで同じことをしないのはなぜですか? ?

例えば、なぜコンパイラーはそうしないのですか?

myHash["myKey"] = ...

そしてそれを

myHash[:myKey] = ...

とにかく、舞台裏で?キーが動的であっても、それはインタプリタなので、値を見つける前にキーがどうなるかを知らなくても、文字列キーをシンボルとして扱う必要がありますか?例えば。:

concatMe = "Key"
myHash["my" + concatMe] = ...

どうして通訳はまだこれを次のように扱うことができないのですか

myHash[:myKey]

それが何を知っているなら

"my" + concatMe

キーで値を検索しますか?

7
AndrewKS

TD; DR:文字列は変更可能です。シンボルはそうではありません。文字列と記号は異なる目的を果たします。

インタプリタは、それをシンボルに一致させるために、入力したWordを解析する必要があります

:foo == "foo"は、文字列をインターンするか、シンボルを文字列に変換することによって決定できます。いずれにせよ、インタプリタが見たすべての文字列をインターンした場合、それらの文字列が変更されたときに多くの追加の作業を行わなければならず、トレードオフは不十分です。また、これらの文字列をガベージコレクションすることもできず、まったくパフォーマンスが低下します。実際、すべての文字列をシンボルに変換することは、現在の動作よりもパフォーマンスがはるかに劣ります。

Rubyは文字列プーリングを使用しません。同じ文字列を多数作成し、インタプリタのメモリ使用量をプロファイリングすることで、これはかなり簡単にわかります。ただし、そのような実装の詳細は、文字列または記号を使用することを決定するときに考慮する必要がある緊張のリストでは非常に低いです。

文字列操作はルックアップテーブルを使用するよりもはるかに遅いことを理解しています

あなたにとって「はるかに遅い」とはどういう意味ですか?サブマイクロ秒のタイミングは「はるかに遅い」のでしょうか?それが私たちが話していることだからです。病理学的な場合を除いて、実際の影響がない、想像上のパフォーマンスの懸念に基づいていない、必要に応じて文字列と記号を使用します。

また、以前に使用されたものと同じか異なるかに関係なく、文字列がメモリに再割り当てされるという考えもありますが、インタプリタはこれを補正できませんか?

はい、参照されなくなったときにガベージコレクションも行われます。シンボルがガベージコレクションされることはありません。これはトレードオフです。

多くの言語(「アトム」を使用するErlangなど)では、文字列は実際には文字(または整数)の単なるリストです。これらの言語では、すべての文字列を内部でシンボルにインターンすることは、さらにコストがかかりすぎます。

7
Rein Henrichs