Frage

Ich habe, was ist im Wesentlichen ein verzweigtes Array von Name-Wert-Paaren - ich brauche eine Reihe von eindeutigen Namen Werte von diesem zu erzeugen. Die gezackte Array ist ca. 86.000 x 11 Werte. Es spielt für mich keine Rolle, welche Art und Weise ich habe einen Namen Wertepaar speichern (eine einzelne Zeichenfolge „Name = Wert“ oder eine spezielle Klasse zum Beispiel KeyValuePair).
Zusätzliche Information:. Es gibt 40 verschiedene Namen und eine größere Anzahl unterschiedlicher Werte - wahrscheinlich in der Region 10.000 Werte

Ich bin mit C # und .NET 2.0 (und die Leistung ist so schlecht, ich denke, dass es besser sein kann meine ganze gezackten Array in einer SQL-Datenbank und tun eine ausgewählte unterscheidet sich von dort zu drücken).

Im Folgenden finden Sie die aktuelle Code Im mit:

List<List<KeyValuePair<string,string>>> vehicleList = retriever.GetVehicles();
this.statsLabel.Text = "Unique Vehicles: " + vehicleList.Count;

Dictionary<KeyValuePair<string, string>, int> uniqueProperties = new Dictionary<KeyValuePair<string, string>, int>();
foreach (List<KeyValuePair<string, string>> vehicle in vehicleList)
{
    foreach (KeyValuePair<string, string> property in vehicle)
    {
        if (!uniqueProperties.ContainsKey(property))
        {
            uniqueProperties.Add(property, 0);
        }
    }
}
this.statsLabel.Text += "\rUnique Properties: " + uniqueProperties.Count;
War es hilfreich?

Lösung

Ich habe es in 0,34 Sekunden läuft unten von 9+ Minuten

Das Problem ist, wenn die KeyValuePair structs zu vergleichen. Ich arbeitete um es durch einen Vergleich Objekt zu schreiben, und Übergeben einer Instanz es dem Wörterbuch.

Von dem, was ich bestimmen kann, die KeyValuePair.GetHashCode () gibt die hashcode davon ist Key Objekt (in diesem Beispiel des am wenigsten einzigartige Objekt).

Wie das Wörterbuch hinzufügt (und prüft Existenz) jedes Element, das die beiden Equals und GetHashCode-Funktionen verwendet, hat aber auf der Equals Funktion verlassen, wenn die Hash-Code weniger eindeutig ist.

eine einzigartige GetHashCode-Funktion Durch die Bereitstellung excerises es die Equals funktionieren weit weniger häufig. Ich optimiert auch die Equals funktionieren die mehr eindeutige Werte vor den weniger unqiue Keys zu vergleichen.

86000 * 11 Einzelteile mit 10.000 einzigartigen Eigenschaften laufen in 0,34 Sekunden unter das comparer-Objekt (ohne das Objekt comparer es dauert 9 Minuten 22 Sekunden)

Hope, das hilft:)

    class StringPairComparer
        : IEqualityComparer<KeyValuePair<string, string>>
    {
        public bool Equals(KeyValuePair<string, string> x, KeyValuePair<string, string> y)
        {
            return x.Value == y.Value && x.Key == y.Key;
        }
        public int GetHashCode(KeyValuePair<string, string> obj)
        {
            return (obj.Key + obj.Value).GetHashCode();
        }
    }

Bearbeiten : Wenn es nur eine Saite (anstelle eines KeyValuePair, wo String = Name + Wert) ist es, so schnell ca. doppelt so hoch sein würde. Es ist ein schönes intresting Problem, und ich verbrachte gaaaaaanz zu viel Zeit auf sie (ich allerdings etwas ruhiger gelernt)

Andere Tipps

Wenn Sie keine spezifische Korrelation müssen zwischen den einzelnen Schlüssel / Wert-Paar und die einzigartigen Werte Sie zu erzeugen, könnten Sie einfach eine GUID verwenden? Ich gehe davon aus dem Problem ist, dass die aktuelle ‚Schlüssel‘ in diesem zerklüfteten Array nicht eindeutig ist.

Dictionary<System.Guid, KeyValuePair<string, string>> myDict 
   = new Dictionary<Guid, KeyValuePair<string, string>>();


foreach of your key values in their current format
   myDict.Add(System.Guid.NewGuid(), new KeyValuePair<string, string>(yourKey, yourvalue))

Klingt wie es würde speichern, was Sie brauchen, aber ich weiß nicht, wie Sie Daten wieder aus diesem ziehen würde, da es keine semantische Beziehung wäre zwischen der Erzeugung Guid & was Sie ursprünglich hatte ...

Können Sie weitere Informationen in Ihrer Frage geben?

Verwenden KeyValuePair als Wrapper-Klasse und erstellen Sie ein Wörterbuch mit einem vielleicht gesetzt zu schaffen? Oder Ihre eigenen Wrapper implementieren, die die Equals überschreiben und GetHashCode.

Dictionary<KeyValuePair, bool> mySet;

for(int i = 0; i < keys.length; ++i)
{
    KeyValuePair kvp = new KeyValuePair(keys[i], values[i]);
    mySet[kvp] = true;
}

Statt einen Dictionary verwenden, warum nicht erweitern KeyedCollection<TKey, TItem> ? Gemäß der Dokumentation:

Stellt die abstrakte Basisklasse für eine Sammlung, deren Schlüssel in den Werten eingebettet ist.

Sie müssen dann die protected TKey GetKeyForItem(TItem item) Funktion außer Kraft zu setzen. Da es sich um eine Hybride aus IList<T> und IDictionary<TKey, TValue> ich denke, es wahrscheinlich ist ziemlich schnell sein

Wie wäre:

Dictionary<NameValuePair,int> hs = new Dictionary<NameValuePair,int>();
foreach (i in jaggedArray)
{
    foreach (j in i)
    {
        if (!hs.ContainsKey(j))
        {
            hs.Add(j, 0);
        }
    }
}
IEnumerable<NameValuePair> unique = hs.Keys;

natürlich, wenn Sie C # 3.0 verwendet haben, .NET 3.5:

var hs = new HashSet<NameValuePair>();
hs.UnionWith(jaggedArray.SelectMany(item => item));

würde den Trick tun.

Haben Profil Sie Ihren Code? Sie sind sicher, dass die foreach-Schleifen der Engpass sind, und nicht retriever.GetVehicles ()?

Ich habe ein kleines Testprojekt erstellen, wo ich die Retriever fälschen und lassen Sie es 86.000 X 11 Werte zurückgeben. Mein erster Versuch lief auf 5 Sekunden, wodurch die Daten enthalten.

habe ich den gleichen Wert sowohl für den Schlüssel und den Wert, wo die erste Taste „0 # 0“ und die letzten „85999 # 10“ war.

Dann wechselte ich zu guids. Gleiches Ergebnis.

Dann habe ich den Schlüssel mehr, wie folgt aus:

        var s = Guid.NewGuid().ToString();
        return s + s + s + s + s + s + s+ s + s + s;

Es dauert nun fast 10 Sekunden.

Dann habe ich die Schlüssel irrsinnig lang und bekam nicht genügend Arbeitsspeicher Ausnahme. Ich habe nicht eine Swap-Datei auf meinem Computer haben, so habe ich diese Ausnahme sofort.

Wie lange sind Ihre Schlüssel? Ist Ihr virtueller Speicherverbrauch der Grund für Ihre schlechte Leistung?

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top