如何降低GetHashCode的复杂性

时间:2013-03-19 13:29:04

标签: c# performance gethashcode

我想减少代码执行时间。看一些测试结果,我发现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访问器中返回一个字节

Sudoku Class中的GetHashCode():

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

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

        return hash;
    }

编辑:网格只是一个类型为Field[,]的多维数组,我只是在这里调用它的属性,它通过它的get访问器返回一个Field [,]网格。

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

4 个答案:

答案 0 :(得分: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的频率(如果您进行任何计算)。或者,如果您将它们存储在某种类型的词典中,则问题可能是具有相同哈希值的多个值,这将减少您对字典/哈希表中对象的访问时间。因此,您的哈希函数必须是您存储的集合的良好分布。

答案 1 :(得分:2)

我怀疑你会发现GetHashCode不是你的问题。如果你花费>在GetHashCode中你有20%的时间,你必须做很多字典查找。或者您正在使用哈希代码来处理您可能不应该使用它的内容。

GetHashCode可能是性能问题的表现,但几乎肯定不是原因。

答案 2 :(得分:1)

如果你的类没有太多的mutator,你可以缓存哈希码,只返回GetHashCode()的缓存值。 (即使你有很多变异器你可以做到这一点,但如果对象经常发生变异,它可能效果会大大降低。)

你应该懒洋洋地评估它。您需要知道它何时脏,需要重新计算。您可以通过添加bool isHashCodeDirty字段轻松完成此操作,该字段在构造类时以及每个mutator方法初始化为true。

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

当然,你必须小心多线程。我认为为GetHashCode()添加锁定会对性能产生很大的影响!

理想当然是拥有不可变的课程;那么你只需在构造函数中计算一次哈希码,之后就不再改变了。

答案 3 :(得分:0)

看起来问题不是整数加法,而是访问像this.Coordinate,this.Grid,e.t.c这样的属性。

看看他们的获取访问者,他们可能正在做一些额外的工作。

相关问题