2009-06-08 8 views
9

非常に大きな(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%のコスト。しかし、ほとんどの場合(自分のものも含めて)、全体的な作業に比べて時間はおそらく無視できる程度です。だから私は今質問がどのように人々は一般的に、コードの保守性を向上させることについて、無視できる程度の性能向上の影響を無視して感じるのでしょうか?

答えて

6

私は静的変数が実際に名前空間、クラス、または関数に属しているかどうかを判断する必要があると言いたいと思います。彼らが実際に関数に固有のものであれば、それらを関数の中に入れます。

関数が範囲外になった後でも状態を保持する変数が必要な場合は、それらをStaticと宣言できます。これは、クラススコープでこれらの変数を持つという問題を排除します。共有クラス変数、静的関数の変数、およびローカル関数の変数間の

違い:

共有:すべてのクラスのインスタンス間で変数のコピーが1つだけになります。

静的:クラスのインスタンスごとに変数のコピーが1つあります。

ローカル:変数のコピーは、関数が呼び出されるたびに作成されますが、関数が有効範​​囲外になると解放されます。

あなたの状況に合ったものを使用してください。

+0

私は実際の測定可能なパフォーマンスについては、違いはおそらく検出不能なほど小さいので心配しているとは思わない。個々のケースをプロファイルする必要性に関係なく、パフォーマンスベースのガイドラインがあります。それが私がここにいるのです。たとえば、ボクシングとアンボクシングのコストのために、可能な場合は値型を扱うために、オブジェクト参照の代わりに強く型付けされた変数を使用するのが一般的です。私の質問は、同様の行に沿って、共有変数ではなくローカル変数を使用する際に考慮すべき大きな費用があるかどうかです。利益/コスト? – BlueMonkMN

+0

実際には定数ですが(VB.NETではローカル定数が使用できますが)、この種の値で定数を宣言することはできないため、変数を宣言する必要があります。そして、同様の質問に遭遇します。クラスの名前空間を汚染しないように余分なインスタンスを持つというオーバーヘッドのコストです。実際には、その特定の機能にのみ適用できる定数です。これは、その関数内で値が処理されているプロパティのプロパティ名のリストです。 – BlueMonkMN

+0

それから静的なローカル変数として宣言します。オーバーヘッドはおそらく非常に小さいので、そのタイプのオブジェクトが何百万も作成されていない限り、クラスの名前空間を汚染しないでおく価値があります。 (1百万オブジェクト=静的変数の100万コピー) –

0

「共有」と言えば、VBで話すのはstaticですか?もしそうなら、慎重でないとスレッディングの危険にさらされる可能性があることに注意してください...そして説明を与えれば、このデータが変更可能なように聞こえるでしょうか?あなたが複数のインスタンス/スレッドを持っていれば "面白い"かもしれません。コンテキストなしで、私はできませんが、再び - ...

インスタンスフィールド(というよりも共有/静的フィールド)私のデフォルトの仮定になりますが説明のコードなしで伝えるのは難しい -

は、たぶん私は過度に偏執されています100%確実です。

+0

はい、VB.Net共有= C#静的 – Pondidum

+3

または==私は言うべきですか? – Pondidum

+0

変更しないでください。私のコメントを参照してください "これは決して変わらないので、これは私には分かりやすいようです"。 – BlueMonkMN

0

私はVB.NETが静的ローカル変数をサポートしていることをほとんど忘れていました。次のテストは、私は、静的ローカル変数を使用して同じように良いパフォーマンスを得ることができることを示しています

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()) 

    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 IsSpecialStatic(params) Then specialCount += 1 
    Next 
    st.Stop() 

    Console.WriteLine("Static: " & 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 

Private Function IsSpecialStatic(ByVal paramList As IEnumerable(Of Integer)) As Boolean 
    Static 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 

出力例:C#は静的ローカル変数をサポートしている場合

Shared: 74836 
00:00:00.0498081 
Local: 75205 
00:00:00.1317149 
Static: 74862 
00:00:00.0469154 

はところで、私はいつも不思議に思っていました、もしそうでなければ、どうしてですか? VB.NETでサポートされているC#には、迷惑な機能がいくつかあります。

+0

これは良いことではありません。非共有関数の静的変数は、すべてのインスタンスでストレージを割り当てます。これは(われわれの状況では)最悪のコストです。静的変数を使って作業する別の共有関数を作成できるかもしれないが、その関数は "名前空間の汚染"になります。私は、今のところ共有クラスの分野に固執しなければならないだろうと思う。 – BlueMonkMN

関連する問題