2015-09-03 17 views
13

ho il seguente per una classe di posizione:Int32.ToString() troppo lento

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

Ma dal momento che io chiamo Pos.ToString() migliaia di volte, questo è troppo lento per me. Tutto ciò di cui ho bisogno è un modo efficiente per ottenere un unico valore univoco basato su Pos.x e Pos.y, da utilizzare come chiave del dizionario. Nota: non riesco a utilizzare Pos perché sto confrontando diverse istanze di Pos solo su x e .

+9

Non utilizzare 'ToString' per le chiavi del dizionario. Implementare 'IEquatable '. –

+5

Non c'è bisogno di 'ToString()' in concatenazione. Basta usare 'x +", "+ y' –

+0

string.Format (" {0}, {1} ", x, y) dovrebbe renderlo leggermente migliore – Yahya

risposta

29

Tutto quello che serve è un modo efficiente per ottenere un singolo valore unico basato sulla Pos.x e Pos.y, da utilizzare come chiave del dizionario.

Non usare ToString come un modo per generare chiavi del dizionario uniche, implementare IEquatable<Pos> invece. In questo modo, non è necessario allocare tutte le stringhe a tutti per misurare l'uguaglianza:

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); 
    } 
} 

Nota è possibile rimuovere il private set dalle dichiarazioni proprietà se si sta utilizzando C# -6.

+2

Un piccolo miglioramento: in C# 6 è possibile rimuovere il 'set privato' dalla X e Proprietà Y. –

+1

Lo so, ma non tutti usano C# 6, quindi sono andato con la versione lenghty. –

+4

Perché "X * 397'? È una costante magica o un numero casuale? – vojta