【问题标题】:Int32.ToString() too slowInt32.ToString() 太慢了
【发布时间】:2015-11-29 07:00:37
【问题描述】:

我有以下职位类别:

public struct Pos
{
    public int x;
    public int y;
    public float height;

    public Pos (int _x, int _y, float _height) 
    {
        x = _x;
        y = _y;
        height = _height;
    }

    public override string ToString () 
    {
        return x.ToString() + "," + y.ToString();
    }
}

但是由于我调用Pos.ToString() 数千次,这对我来说太慢了。我所需要的只是一种基于Pos.xPos.y 获取单个唯一值的有效方法,用作字典键。 注意:我不能使用Pos,因为我仅在xy 上比较Pos 的不同实例。

【问题讨论】:

  • 不要将ToString 用作字典键。改为实现IEquatable<Pos>
  • 不需要ToString() 串联。只需使用x + "," + y
  • 使用(long) ((x << 32) | y) 作为字典键怎么样?我想它会快得多。
  • @Yahya 慢 100 倍并不意味着更快。 string.format 执行您可以手动执行的相同连接工作。此外,它还必须进行格式字符串处理。它不会以任何方式剥夺工作。它增加了。
  • @X-TECH 最终还是会调用ToString

标签: c# performance dictionary hash tostring


【解决方案1】:

我所需要的只是一种有效的方法来获得基于 Pos.x 和 Pos.y,用作字典键。

不要使用ToString 作为生成唯一字典键的方法,而是实现IEquatable<Pos>。这样,您根本不必分配任何字符串来衡量相等性:

public struct Pos : IEquatable<Pos>
{
    public int X { get; private set; }
    public int Y { get; private set; }
    public float Height { get; private set; }

    public Pos(int x, int y, float height)
    {
        X = x;
        Y = y;
        Height = height;
    }

    public bool Equals(Pos other)
    {
        return X == other.X && Y == other.Y;
    }

    public override bool Equals(object obj)
    {
        if (ReferenceEquals(null, obj)) return false;
        return obj is Pos && Equals((Pos) obj);
    }

    public override int GetHashCode()
    {
        unchecked
        {
            return (X*397) ^ Y;
        }
    }

    public static bool operator ==(Pos left, Pos right)
    {
        return left.Equals(right);
    }

    public static bool operator !=(Pos left, Pos right)
    {
        return !left.Equals(right);
    }
}

请注意,如果您使用 C#-6,则可以从属性声明中删除 private set

【讨论】:

  • 一个微小的改进:在 C#6 中,您可以从 X 和 Y 属性中删除 private set
  • 我知道,但不是每个人都在使用 C#6,所以我选择了长版本。
  • @vojta 您想使用大素数,因为您想尝试避免冲突。见this post
  • const int OPTIMUS_PRIME = 397; // GetHashCode() 中的局部常量
  • 由于这个类是不可变的,你可以通过在构造函数中计算一次哈希而不是每次调用GetHashCode来获得小的性能提升。这将以散列的额外存储为代价。
猜你喜欢
  • 1970-01-01
  • 2013-03-10
  • 2014-06-07
  • 2016-05-31
  • 2011-07-07
  • 2015-08-23
  • 2012-07-05
  • 2016-01-08
  • 2014-03-12
相关资源
最近更新 更多