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 只是一个类型的多维数组:Field[,],我只是在这里调用它的属性,它通过它的 get 访问器返回一个 Field[,] 网格。

问题:如何大大降低 GetHashCode() 的复杂性并提高其性能?为什么 GetHashCode() 方法的性能如此之低?

4

4 回答 4

2

您的计算只是在您的哈希码中添加一个 conts。只有哈希码的组合需要有更好的哈希码,然后只需添加两个值:

//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,并且也由每个 mutator 方法初始化。

然后在GetHashCode()ifisHashCodeDirty为 true 的实现中,将其设置为 false 并重新计算并返回哈希码。如果为假,则只返回缓存的值。

当然,你必须小心这里的多线程。我认为向 GetHashCode() 添加锁会极大地影响性能!

理想的当然是拥有不可变的类;然后你只需在构造函数中计算一次哈希码,之后它就永远不会改变。

于 2013-03-19T13:51:22.360 回答
0

看起来问题不在于整数加法,而在于访问 this.Coordinate、this.Grid 等属性

看看他们的 get 访问器,他们可能正在做一些额外的工作。

于 2013-03-19T13:31:33.313 回答