非常に大きな(DataContextから派生した)クラスの部分クラスに追加された、数多くの新しいプライベート共有変数(宣言で初期化されたHashtables(Of String)型)を発見しました。これは決して変わらないので、私にとっては分かりやすいようです。これらの共有変数を作ることで、関数が呼び出されるたびに再初期化されないようになります。しかし、これらの変数はであり、クラス内の1つの関数の範囲内でのみ使用されています。このDataContextから派生したクラスのプライベートな名前空間が汚染されていることが懸念されます。将来コードを読んでいる人たちに混乱を招く可能性があります。関数内でこれらのローカル変数を使用する際にパフォーマンスに悪影響を与えるか、これを処理するためのよりよい方法がありますか?基本的には、これらの3つのハッシュテーブルを使用して、特定のプロパティのサブセット内のものが変更されたかどうかを確認しています(GetModifiedMembersを使用して、ハッシュセットのオーバーラップ関数を使用して、変更されたメンバーが関心のあるメンバーに対応しているかどうかを確認します)。プライベート共有変数vsローカル変数/名前空間公害対パフォーマンス?
編集: 私は自分自身のテストプログラムを書く時間を要しました。ローカル変数を使用するコストがあることが確認されました(これは一般的にすべてのケースに当てはまります - 私は、共有変数を使用して適切にこれを行うには、いくつかの追加のロジックを必要としない限り、変数は)遅くなることになります。
Sub Main()
Dim st As New Stopwatch()
Dim specialCount As Integer = 0
Dim r As New Random()
Dim params As Integer()
ReDim params(0 To 9)
st.Start()
For i As Integer = 1 To 100000
For j As Integer = 0 To 9
params(j) = r.Next(100)
Next
If IsSpecialShare(params) Then specialCount += 1
Next
st.Stop()
Console.WriteLine("Shared: " & specialCount)
Console.WriteLine(st.Elapsed.ToString())
st.Reset()
specialCount = 0
st.Start()
For i As Integer = 1 To 100000
For j As Integer = 0 To 9
params(j) = r.Next(100)
Next
If IsSpecialLocal(params) Then specialCount += 1
Next
st.Stop()
Console.WriteLine("Local: " & specialCount)
Console.WriteLine(st.Elapsed.ToString())
End Sub
Dim specialListShared As New HashSet(Of Integer)(New Integer() {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41})
Private Function IsSpecialLocal(ByVal paramList As IEnumerable(Of Integer)) As Boolean
Dim specialListLocal As New HashSet(Of Integer)(New Integer() {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41})
Return specialListLocal.Overlaps(paramList)
End Function
Private Function IsSpecialShare(ByVal paramList As IEnumerable(Of Integer)) As Boolean
Return specialListShared.Overlaps(paramList)
End Function
サンプル出力:
Shared: 75232
00:00:00.0408223
Local: 75018
00:00:00.1344628
だから、この特定のケースでは、ローカル変数を使用すると、約200%のコスト。しかし、ほとんどの場合(自分のものも含めて)、全体的な作業に比べて時間はおそらく無視できる程度です。だから私は今質問がどのように人々は一般的に、コードの保守性を向上させることについて、無視できる程度の性能向上の影響を無視して感じるのでしょうか?
私は実際の測定可能なパフォーマンスについては、違いはおそらく検出不能なほど小さいので心配しているとは思わない。個々のケースをプロファイルする必要性に関係なく、パフォーマンスベースのガイドラインがあります。それが私がここにいるのです。たとえば、ボクシングとアンボクシングのコストのために、可能な場合は値型を扱うために、オブジェクト参照の代わりに強く型付けされた変数を使用するのが一般的です。私の質問は、同様の行に沿って、共有変数ではなくローカル変数を使用する際に考慮すべき大きな費用があるかどうかです。利益/コスト? – BlueMonkMN
実際には定数ですが(VB.NETではローカル定数が使用できますが)、この種の値で定数を宣言することはできないため、変数を宣言する必要があります。そして、同様の質問に遭遇します。クラスの名前空間を汚染しないように余分なインスタンスを持つというオーバーヘッドのコストです。実際には、その特定の機能にのみ適用できる定数です。これは、その関数内で値が処理されているプロパティのプロパティ名のリストです。 – BlueMonkMN
それから静的なローカル変数として宣言します。オーバーヘッドはおそらく非常に小さいので、そのタイプのオブジェクトが何百万も作成されていない限り、クラスの名前空間を汚染しないでおく価値があります。 (1百万オブジェクト=静的変数の100万コピー) –