有幾種實現方法。 James Henstridge實際上有一個好主意,我試圖實現它。它表現得相當不好,只是使用地圖,沒有我自己的哈希算法。
我解決這個問題的方法只是保留你的結構數組,然後在插入它們時刪除任何重複項。
package structset
type Foo struct {
title string
Tags map[string]string
}
func (f Foo) Equals(f2 Foo) bool {
if f.title != f2.title {
return false
}
if len(f.Tags) != len(f2.Tags) {
return false
}
for k, v := range f.Tags {
if w, ok := f2.Tags[k]; !ok || v != w {
return false
}
}
return true
}
type FooSet []Foo
func (this FooSet) Add(value Foo) {
if !this.Contains(value) {
this = append(this, value)
}
}
func (this FooSet) Length() int {
return len(this)
}
func (this FooSet) Contains(f Foo) bool {
for _, v := range this {
if v.Equals(f) {
return true
}
}
return false
}
func NewSet() FooSet {
return FooSet(make([]Foo, 0, 100))
}
我這個基準我i7-3770K Windows機器上,並得到:
BenchmarkSmallSetWithFewCollisions 50000 46615 ns/op
BenchmarkSmallSetWithMoreCollisions 50000 46575 ns/op
BenchmarkSmallSetWithManyCollisions 50000 46605 ns/op
BenchmarkMediumSetWithFewCollisions 1000 2335296 ns/op
BenchmarkMediumSetWithMoreCollisions 1000 2352298 ns/op
BenchmarkMediumSetWithManyCollisions 1000 2336796 ns/op
BenchmarkLargeSetWithFewCollisions 50 46805944 ns/op
BenchmarkLargeSetWithMoreCollisions 50 47376016 ns/op
BenchmarkLargeSetWithManyCollisions 50 46815946 ns/op
要伊克出來的性能極少量的,您可以先插入所有數據到數組,然後刪除所有重複項後。
的刪除重複的代碼是:
func (this FooSet) RemoveDuplicates() {
length := len(this) - 1
for i := 0; i < length; i++ {
for j := i + 1; j <= length; j++ {
if this[i].Equals(this[j]) {
this[j] = this[length]
this = this[0:length]
length--
j--
}
}
}
}
的基準是這樣的:
BenchmarkSmallSetWithFewCollisions 50000 45245 ns/op
BenchmarkSmallSetWithMoreCollisions 50000 45615 ns/op
BenchmarkSmallSetWithManyCollisions 50000 45555 ns/op
BenchmarkMediumSetWithFewCollisions 1000 2294791 ns/op
BenchmarkMediumSetWithMoreCollisions 1000 2309293 ns/op
BenchmarkMediumSetWithManyCollisions 1000 2286290 ns/op
BenchmarkLargeSetWithFewCollisions 50 46235870 ns/op
BenchmarkLargeSetWithMoreCollisions 50 46515906 ns/op
BenchmarkLargeSetWithManyCollisions 50 45865824 ns/op
這裏是剛剛分配的Foo到地圖[字符串]美孚的基準。
BenchmarkSmallSetWithFewCollisions 50000 65718 ns/op
BenchmarkSmallSetWithMoreCollisions 50000 64238 ns/op
BenchmarkSmallSetWithManyCollisions 50000 55016 ns/op
BenchmarkMediumSetWithFewCollisions 500 3429435 ns/op
BenchmarkMediumSetWithMoreCollisions 500 3117395 ns/op
BenchmarkMediumSetWithManyCollisions 1000 2826858 ns/op
BenchmarkLargeSetWithFewCollisions 20 82635495 ns/op
BenchmarkLargeSetWithMoreCollisions 20 85285830 ns/op
BenchmarkLargeSetWithManyCollisions 20 73659350 ns/op
在我看來,即使地圖是可散的,它仍然不會表現的很好。
我想你可能想'DeepEqual'。 –
你真的需要'map [string] string',通常地圖集是'map [string] bool'嗎? –
@WesFreeman:尋找結構的集合,而不僅僅是結構 –