Golang中的地图集

Golang中的地图集,第1张

概述如果我有一个像这样的结构: type Foo struct { title string Tags map[string]string} 如何保持一套独特的结构?根据我的理解,虽然结构相等是一件事 – 地图平等不是.这意味着我无法比较我的上述结构.因此,我不能只实施map as set pattern. 我能想到的两个可能有用的选项是:将标签转换为排序的[] []字符串或use refl 如果我有一个像这样的结构:
type Foo struct {  Title string  Tags map[string]string}

如何保持一套独特的结构?根据我的理解,虽然结构相等是一件事 – 地图平等不是.这意味着我无法比较我的上述结构.因此,我不能只实施map as set pattern.

我能想到的两个可能有用的选项是:将标签转换为排序的[] []字符串或use reflect.Deepequal.任何人都有更好的主意?

有几种方法可以实现这一点. James HenstrIDge实际上有一个好主意,我试图实现它.如果没有我自己的哈希算法,它首先使用map就表现得非常糟糕.

我解决这个问题的方法就是保留一个结构数组,然后在插入它们时删除任何重复项.

package structsettype 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 []Foofunc (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,100))}

我在i7-3770K windows机器上对此进行了基准测试,得到了:

BenchmarkSmallSetWithFewCollisions         50000             46615 ns/opBenchmarkSmallSetWithMoreCollisions        50000             46575 ns/opBenchmarkSmallSetWithManyCollisions        50000             46605 ns/opBenchmarkMediumSetWithFewCollisions         1000           2335296 ns/opBenchmarkMediumSetWithMoreCollisions        1000           2352298 ns/opBenchmarkMediumSetWithManyCollisions        1000           2336796 ns/opBenchmarkLargeSetWithFewCollisions            50          46805944 ns/opBenchmarkLargeSetWithMoreCollisions           50          47376016 ns/opBenchmarkLargeSetWithManyCollisions           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/opBenchmarkSmallSetWithMoreCollisions        50000             45615 ns/opBenchmarkSmallSetWithManyCollisions        50000             45555 ns/opBenchmarkMediumSetWithFewCollisions         1000           2294791 ns/opBenchmarkMediumSetWithMoreCollisions        1000           2309293 ns/opBenchmarkMediumSetWithManyCollisions        1000           2286290 ns/opBenchmarkLargeSetWithFewCollisions            50          46235870 ns/opBenchmarkLargeSetWithMoreCollisions           50          46515906 ns/opBenchmarkLargeSetWithManyCollisions           50          45865824 ns/op

这是将Foo分配给地图[string] Foo的基准.

BenchmarkSmallSetWithFewCollisions         50000             65718 ns/opBenchmarkSmallSetWithMoreCollisions        50000             64238 ns/opBenchmarkSmallSetWithManyCollisions        50000             55016 ns/opBenchmarkMediumSetWithFewCollisions          500           3429435 ns/opBenchmarkMediumSetWithMoreCollisions         500           3117395 ns/opBenchmarkMediumSetWithManyCollisions        1000           2826858 ns/opBenchmarkLargeSetWithFewCollisions            20          82635495 ns/opBenchmarkLargeSetWithMoreCollisions           20          85285830 ns/opBenchmarkLargeSetWithManyCollisions           20          73659350 ns/op

在我看来,即使地图是可以清洗的,它仍然表现不佳.

总结

以上是内存溢出为你收集整理的Golang中的地图集全部内容,希望文章能够帮你解决Golang中的地图集所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1293732.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-10
下一篇 2022-06-10

发表评论

登录后才能评论

评论列表(0条)

保存