1

次の方法を取ります (Ruby で記述されていますが、この質問はほとんどの OO 言語に適用できます)。

# Getter method which returns an alert
def alertView
  _alertView = AlertView.new
  _alertView.title = "This is the title"
  _alertView.body = "This is the body of my alert"
  _alertView
end

このメソッドは、アプリケーションのライフサイクルを通じて定期的に呼び出されるとします。タイトルと本文の属性文字列は、毎回新しいオブジェクトとしてインスタンス化されます。

これを最適化するには、次のようにします。

ALERT_TITLE = "This is the title"
ALERT_BODY  = "This is the body of my alert"

# Getter method which returns an alert
def alertView
  _alertView = AlertView.new
  _alertView.title = ALERT_TITLE
  _alertView.body = ALERT_BODY
  _alertView
end

このように、文字列ALERT_TITLEALERT_BODY文字列は、クラスが定義されたときに 1 回だけインスタンス化され、アプリケーションのライフサイクル全体で再利用されます。

私の質問は: 2 番目のアプローチは最適ですか? これは、ガベージ コレクターの作業が減り、メモリの使用が安定することを意味しますが、現在必要のないオブジェクトを解放するのではなく、アプリケーションが常により多くのメモリを消費していることも意味します。これをアプリケーション内のすべての定数文字列に適用するか、このアプローチをまったく適用せず、必要に応じて各文字列を定義するかで迷っています。

3 番目のアプローチはクラス変数を使用することですが、これが 2 番目のアプローチより優れている点は、変数が遅延ロードされることだけです。

# Getter method which returns an alert
def alertView
  _alertView = AlertView.new
  _alertView.title = @@alert_title ||= "This is the title"
  _alertView.body = @@alert_body ||= "This is the body of my alert"
  _alertView
end
4

2 に答える 2

3

上記の 2 つのバリアントは完全に等しいわけではありません。観察:

1.9.3p194 :001 > A = 'a'
 => "a" 
1.9.3p194 :002 > s1 = A # constant assignment
 => "a" 
1.9.3p194 :003 > s2 = A
 => "a" 
1.9.3p194 :004 > s1 << 'b'
 => "ab" 
1.9.3p194 :005 > s2 # you changed s2 as well!
 => "ab" 
1.9.3p194 :006 > s1 = 'a' # literal assignment
 => "a" 
1.9.3p194 :007 > s2 = 'a'
 => "a" 
1.9.3p194 :008 > s1 << 'b'
 => "ab" 
1.9.3p194 :009 > s2 # s2 stayed the same.
 => "a" 

2 つの変数に同じ定数が割り当てられている場合でも、メモリ内には文字列のインスタンスが1 つしかありません。リテラル文字列を割り当てると、すべての変数がメモリ内に独自のインスタンスを持ちます (これは、別のコメントで正しく指摘したシンボルには当てはまりません)。したがって、すべては、達成したい (または回避したい) こと、作成するインスタンスの数などによって異なります。

あなたの例のように、質問が本当に文字列に関するものである場合、効率を気にするのをやめて、コードの読みやすさを気にし始める思います.

したがって、プログラマーの観点から、よりクリーンだと思われることは何でも行うことをお勧めします。

于 2012-06-24T17:30:13.140 に答える
0

とにかく、C# と Java では、これらは等しく最適です。「文字列インターン」と呼ばれるものにより、コンパイラは毎回同じ文字列をインスタンス化していることを認識し、新しい AlertView オブジェクトごとに、使用している 2 つの文字列に対して同じ 2 つのオブジェクト参照を与えます。

さて、Ruby はインタープリター言語であり、... C# や Java ではありません...これが実現するかどうかはわかりません。だから、うまくいけば、他の誰かも答えてくれるでしょう。しかし、私の最初の推測では、文字列の内部化を実装しているということです。単純に、解釈されていても、文字列定数に遭遇したときに文字列定数を簡単に認識し、他の言語が処理するのと同じ (最適化された) 方法で処理できるはずだからです。

于 2012-06-24T16:18:04.960 に答える