2017-05-19 2 views
1

Ich analysiere eine große Anzahl von HTTP-Protokollen mit einem Ziel und gebe an, wie viele Anfragen jede IP-Adresse generiert hat.Golang: optimale Art der Eingabe von assoziativen Slices?

Das erste, was ich tat, ist:

var hits = make(map[string]uint) 

// so I could populate it with 
hits[ipAddr]++ 

Allerdings würde ich es gerne machen „getippt“, so dass es sofort klar wäre, dass hits[string]uint eine IP-Adresse als String Kennung verwendet. Ich dachte, vielleicht auch eine Struktur kann mir helfen:

type Hit struct { 
    IP string 
    Count uint 
} 

Aber auf diese Weise (ich glaube) ich die Leistung zu verlieren, weil ich jetzt, wie man wirklich spezifischen Hit suche es Zahl zu erhöhen. Ich tolerieren, dass ich hier paranoid sein könnte, und einfach für die Schleife gehen könnte:

var hits = make([]Hit) 

// TrackHit just damn tracks it 
func TrackHit(ip string) { 
    for hit, _ := range hits { 
     if hit.IP == ip { 
      hit.Count++ 
      return 
     } 
    } 

    append(hits, Hit{ 
     IP: ip, 
     Count: 0, 
    }) 
} 

Aber das sieht einfach ... suboptimal. Ich denke, alles, was in einer Zeile geschrieben werden kann, lässt dich als Profi glänzen, und wenn eine Zeile zu 13 wird, tendiere ich dazu, "whaaa? Etwas falsch zu machen, Mama?"

Irgendein getippter Einzeiler hier in Go?

Dank

+4

Typ IP-Zeichenfolge; Typ Hits map [IP] uint – Uvelichitel

+0

und dann 'hits [IP {ipAddr}] ++'? Und wenn ja, weist es doppelt so viel Speicher zu, weil wir bei jeder Schleife, die wir durchlaufen, eine neue IP erstellen? –

+1

Treffer [IP ("127.0.0.1")] ++; Es ist mehr oder weniger idiomatisch. – Uvelichitel

Antwort

4

Wie Uvelichitel darauf hingewiesen, können Sie eine typisierte Zeichenfolge verwenden:

type IP string 
var hits = make(map[IP]uint) 
hits[IP("127.0.0.1")]++ 

Oder Sie könnten den bestehenden stdlib IP-Typ:

var hits = make(map[net.IP]uint) 
hits[net.ParseIP("127.0.0.1")]++ 

Entweder würde es deutlich machen, dass Sie sich auf IPs beziehen, ohne den Overhead, der durch das Durchlaufen eines Segments von Strukturen für jedes Inkrement eingeführt wird. Letzteres hat den Vorteil, dass Sie volle stdlib-Unterstützung für jede andere IP-Manipulation, die Sie ausführen müssen, und eine kompaktere Darstellung (4 Bytes für IPv4-Adressen statt einer 7-15-Zeichen langen UTF-8-Zeichenfolge) auf Kosten des Parsens erhalten die Saiten. Welche davon besser ist, hängt von Ihrem spezifischen Anwendungsfall ab.

+0

Vielen Dank für die umfassende Antwort, @Adrian. Wie würde ich eine weitere Gruppierungsebene erstellen? Sprich, zuerst würde ich nach Anfrage Datum gruppieren, dann auf Anfrage IP? Würde 'hits [Datum (" 2017/May/1 ")] [net.ParseIP (" 127.0.0.1 ")] ++' Arbeit? Wäre ich in der Lage, es zu benutzen, ohne explizit zu überprüfen, ob '[Date ((2017/May/1))]' zuerst existiert? –

+0

Oder soll ich 'type RequestGroup struct {Datumsstring, IP net.IP}' definieren und dann 'hits = make (map [ReqeustGroup] uint)'? –