2017-05-19 10 views
1

私は目的を追求するHTTPログのロードを解析して、各IPアドレスが生成された要求の数を示します。Golang:連想スライスを入力する最適な方法は?

私がした最初の事は次のとおりです。ただし

var hits = make(map[string]uint) 

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

hits[string]uintは、文字列の識別子としてIPアドレスを使用していること、それはすぐに明らかになるように、私は、それは「型付け」したいと思います。私はよく、多分構造体は私を助けることができる、と思った:

type Hit struct { 
    IP string 
    Count uint 
} 

しかし、そのように(私が思う)今、私はどのように実際にそれが数だインクリメントする具体的なヒットを探すために、ので、私は、パフォーマンスを失いますよ。私はここでは妄想になることができると容認し、ループのために簡単に行くことができます:

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

しかし、それはちょっと...次善のようです。私は1行で書くことができるすべてがプロとして輝きます、そして、1行が13に変わるとき、私は "whaaa?ここで間違ったことをしています、ママ?

ここに「Go」と入力してください。

おかげ

+4

タイプIP文字列;タイプヒットマップ[IP] uint – Uvelichitel

+0

そして 'ヒット[IP {ipAddr}] ++'?そしてもしそうなら、2倍のメモリを割り当てますか?ループする各文字列に新しいIPを作成するからです。 –

+1

ヒット[IP( "127.0.0.1")] ++;それは多かれ少なかれ慣用的な方法です。 – Uvelichitel

答えて

4

Uvelichitelが指摘したように、入力した文字列を使用することができます。

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

または既存STDLIB IPタイプを使用できます。どちらかは、それが明確になるだろう

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

をすべてのインクリメントに対して構造体のスライスをループすることによってオーバーヘッドが導入されることなく、IPを参照しているということです。後者は、必要な他のIP操作を完全にstdlibでサポートするという利点があります。構文解析の代償として、よりコンパクトな表現(7-15文字のUTF-8文字列ではなくIPv4アドレスの場合は4バイト)弦。どちらが優れているかは、特定のユースケースに依存します。

+0

@Adrianの包括的な回答ありがとうございます。別のグループ化レベルをどうやって作るのですか?さあ、まずはリクエスト日までにグループ化したいのですが、その後リクエストIPでグループ化したいのですか? 'ヒット[Date(" 2017/May/1 ")] [net.ParseIP(" 127.0.0.1 ")] ++' work? 'ヒット[Date(" 2017/May/1 ")]が最初に存在するかどうかを明示的にチェックしなくてもそれを使うことはできますか? –

+0

また、 'type RequestGroup struct {Date string、IP net.IP}'と 'hits = make(map [ReqeustGroup] uint)'を定義する必要がありますか? –

関連する問題