标签:实现 UI exist add bsp hub font dex 情况
开发 hashset 常用的套路:
map[int]int8 map[int]bool
我们一般只用 map 的键来保存数据,值是没有用的。所以来缓存集合数据会造成内存浪费。
空对象是个神奇的东西。它指的是没有字段的结构类型。
type Q struct{}
它牛逼的地方在于:
可以和普通结构一样操作
var a = []struct{}{struct{}{}} fmt.Println(len(a)) // prints 1
不占用空间
var s struct{} fmt.Println(unsafe.Sizeof(s)) // prints 0
声明两个空对象,它们指向同一个地址
type A struct{} a := A{} b := A{} fmt.Println(&a == &b) // prints true
造成这个结果的原因是 Golang 的编译器会把这种空对象都当成 runtime.zerobase
处理。
var zerobase uintptr
有了上面的介绍,就可以利用空结构来优化 hashset 了。
var itemExists = struct{}{} type Set struct { items map[interface{}]struct{} } func New() *Set { return &Set{items: make(map[interface{}]struct{})} } func (set *Set) Add(item interface{}) { set.items[item] = itemExists } func (set *Set) Remove(item interface{}) { delete(set.items, item) } func (set *Set) Contains(item interface{}) bool { if _, contains := set.items[item]; !contains { return false } return true }
一个简易的 hashset 实现就完成了。
func BenchmarkIntSet(b *testing.B) { var B = NewIntSet(3) B.Set(10).Set(11) for i := 0; i < b.N; i++ { if B.Exists(1) { } if B.Exists(11) { } if B.Exists(1000000) { } } } func BenchmarkMap(b *testing.B) { var B = make(map[int]int8, 3) B[10] = 1 B[11] = 1 for i := 0; i < b.N; i++ { if _, exists := B[1]; exists { } if _, exists := B[11]; exists { } if _, exists := B[1000000]; exists { } } } BenchmarkIntSet-2 50000000 35.3 ns/op 0 B/op 0 allocs/op BenchmarkMap-2 30000000 41.2 ns/op 0 B/op 0 allocs/op
标签:实现 UI exist add bsp hub font dex 情况
原文地址:http://www.cnblogs.com/logo-fox/p/6985598.html