2

コードの実行時間を短縮したい。いくつかのテスト結果を見ると、GetHashCode() が実行時間の 21.62% を占めていることがわかりました。

私も警告を受けました:

警告 1 DA0010: .*.GetHashCode() = 7,63; GetHashCode 関数は安価で、メモリを割り当てないようにする必要があります。可能であれば、ハッシュ コード関数の複雑さを減らします。

コード スニペット:

フィールドクラスの私の GetHashCode():

    public override int GetHashCode()
    {
        int hash = 7;
        hash = (hash * 13) + this.Coordinate.GetHashCode();
        return hash;
    }

座標クラスの私の GetHashCode():

    public override int GetHashCode()
    {
        int hash = 17;

        hash = (hash * 23) + this.Row.GetHashCode();
        hash = (hash * 23) + this.Column.GetHashCode();

        return hash;
    }

編集:行と列は単なるバイト変数です。getアクセサーでバイトを返すプロパティを呼び出すだけです

数独クラスの私の GetHashCode():

    public override int GetHashCode()
    {
        int hash = 7;

        hash = (hash * 5) + this.Grid.GetHashCode();

        return hash;
    }

編集: Grid は type: の単なる多次元配列です。Field[,]ここでは、 get アクセサーを介して Field[,] グリッドを返す Property と呼んでいます。

質問: GetHashCode() の複雑さを大幅に軽減し、パフォーマンスを向上させるにはどうすればよいですか? GetHashCode() メソッドのパフォーマンスが非常に低いのはなぜですか?

4

4 に答える 4

2

あなたの計算は、ハッシュコードに conts を追加するだけです。ハッシュコードの組み合わせのみが、2 つの値を追加するよりも優れたハッシュコードを持つ必要があります。

//Field 
public override int GetHashCode()
{
    return this.Coordinate.GetHashCode();
}

//Coordinate 
public override int GetHashCode()
{
    return  this.Column.GetHashCode() * 17 + this.Row.GetHashCode();
}    

//Sudoku, I doubt if this is ever called...
public override int GetHashCode()
{
    return this.Grid.GetHashCode();
}

パフォーマンスについては、GetHashCode を呼び出す頻度に大きく依存します (計算を行う場合)。または、それらをある種のディクショナリに保存すると、同じハッシュを持つ複数の値が問題になる可能性があり、ディクショナリ/ハッシュテーブル内のオブジェクトへのアクセス時間が短縮されます。したがって、ハッシュ関数は、保存しているセットの適切な分散でなければなりません。

于 2013-03-19T13:38:32.320 に答える
2

GetHashCodeそれはあなたの問題ではないことがわかると思います。で 20% を超える時間を費やしている場合はGetHashCode、大量の辞書検索を行っているに違いありません。または、ハッシュコードをおそらく使用すべきではないものに使用しています。

GetHashCodeパフォーマンスの問題の現れかもしれませんが、それが原因ではないことはほぼ確実です。

于 2013-03-19T13:42:02.860 に答える
1

クラスにあまり多くのミューテーターがない場合は、ハッシュ コードをキャッシュして、キャッシュされた値を から返すことができますGetHashCode()。(多数のミューテーターが存在する場合でもこれを行うことができますが、オブジェクトが頻繁にミューテーションされる場合、効果が大幅に低下する可能性があります。)

あなたはそれを怠惰に評価すべきです。いつ汚れて再計算が必要になるかを知る必要があります。これは、フィールドを追加することで簡単に行うことができます。このbool isHashCodeDirtyフィールドは、クラスの構築時およびすべてのミューテーター メソッドによって true に初期化されます。

GetHashCode()次に、 if isHashCodeDirtyis trueの実装でfalse に設定し、再計算してハッシュ コードを返します。false の場合は、キャッシュされた値を返すだけです。

もちろん、ここではマルチスレッドに注意する必要があります。ただし、GetHashCode() にロックを追加すると、パフォーマンスに大きな影響を与えると思います!

もちろん、理想は不変のクラスを持つことです。次に、コンストラクターでハッシュ コードを 1 回計算するだけで、それ以降変更されることはありません。

于 2013-03-19T13:51:22.360 に答える
0

問題は整数の加算ではなく、this.Coordinate、this.Grid などのプロパティへのアクセスにあるようです。

彼らの get アクセサーを見てください。彼らは余分な仕事をしているかもしれません。

于 2013-03-19T13:31:33.313 に答える