golang使用map支持高并发的方法(1000万次操作14ms)

 更新时间:2022年11月15日 10:43:47   作者:飞鸟真人  
这篇文章主要介绍了golang使用map支持高并发的方法(1000万次操作14ms),本文给大家详细讲解,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

语言原生的map存在2个问题:

1)不是线程安全的;

2)数据量大时候需要尽量避免使用string等,GC压力很大;

有人使用泛型实现了相关的cocurent-map,(https://github.com/orcaman/concurrent-map)但是关于键值部分仍然默认使用了string,为了提高效率,这里对其做了一些修改,让键值也可以自定义类型:https://github.com/robinfoxnan/go_concurrent_map

基本使用方法:

	// Create a new map.
	m := cache.NewConcurrentMap[uint64, string]()
 
	// Sets item within map, sets "bar" under key "foo"
	m.Set(199010212, "bar")
 
	// Retrieve item from map.
	bar, ok := m.Get(199010212)
	fmt.Println(bar, ok)
 
	// Removes item under key "foo"
	m.Remove(199010212)

为了实现计数器等,需要在加锁期间更新,需要使用回调函数:

// 计数器
type BaseCounter struct {
	Count     uint64
	CountLast uint64
}
 
var MapOfAppUserCount ConcurrentMap[uint64, *AppUserCounter]
 
func InitMaps() {
	MapOfAppVistedCount = NewConcurrentMap[uint64, *BaseCounter]()
}
 
// 没有值,则设置;如果有,则更新; 新增的部分通过新的值传递过来!
func appAddCallBack(exist bool, valueInMap *BaseCounter, newValue *BaseCounter) *BaseCounter {
	if exist == false {
		return newValue
	} else {
		valueInMap.Count += newValue.Count
		return valueInMap
	}
}
 
// 对应用计数器加i
func AppAddBy(key uint64, i uint64) uint64 {
	c := BaseCounter{i, i}
	res := MapOfAppVistedCount.Upsert(key, &c, appAddCallBack)
	if res != nil {
		return res.Count
	}
	return 0
}

计数器的使用如下:

cache.InitMaps()
cache.AppAddBy(i, 1)

性能:

1)单线程初始化1~1000w的计数器,2412  ms

2)分给100个协程,14ms

测试代码如下:

 func testSingle() {
	cache.InitMaps()
	timeUnixNano1 := time.Now().UnixMilli()
	// 100万次更新
	for i := uint64(0); i < 10000000; i++ {
		cache.AppAddBy(i, 1)
	}
	timeUnixNano2 := time.Now().UnixMilli()
	delta := timeUnixNano2 - timeUnixNano1
	fmt.Println("cost: ", delta, " ms")
 
	count := cache.AppAddBy(1, 1)
	fmt.Println(count)
	count = cache.AppAddBy(1, 2)
	fmt.Println(count)
	count = cache.AppAddBy(1, 3)
	fmt.Println(count)
}
 
var N int = 10000000
 
func doInsert(n int, index int, g *sync.WaitGroup) {
	m := N / n
	start := index * m
 
	//fmt.Println("thread ", index, "from ", start)
	for i := uint64(start); i < uint64(m); i++ {
		cache.AppAddBy(i, 1)
	}
	if g != nil {
		g.Done()
	}
}
 
func testMulti() {
	cache.InitMaps()
 
	group := sync.WaitGroup{}
	n := 100
	group.Add(n)
	timeUnixNano1 := time.Now().UnixMilli()
	for i := 0; i < n; i++ {
		go doInsert(n, i, &group)
	}
	group.Wait()
	timeUnixNano2 := time.Now().UnixMilli()
	delta := timeUnixNano2 - timeUnixNano1
	fmt.Println("cost: ", delta, " ms")
 
}

到此这篇关于golang让map支持高并发(1000万次操作14ms)的文章就介绍到这了,更多相关golang map并发内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 在Golang中使用iota案例详解

    在Golang中使用iota案例详解

    在Go语言中,iota是一个预定义的标识符,用于在常量声明中生成连续的递增值,iota的值从0开始,每次在常量声明中使用时递增,本就给大家讲解一下Golang中iota的使用案例,感兴趣的同学跟着小编一起来看看吧
    2023-07-07
  • Go+Kafka实现延迟消息的实现示例

    Go+Kafka实现延迟消息的实现示例

    本文主要介绍了Go+Kafka实现延迟消息的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-07-07
  • Golang多线程刷票的实现代码

    Golang多线程刷票的实现代码

    这篇文章主要介绍了Golang多线程刷票的相关资料,这里实现刷票的功能,对于投票,刷票的很方便,并附实现代码,需要的朋友可以参考下
    2017-07-07
  • 使用golang脚本基于kubeadm创建新的token(问题分析)

    使用golang脚本基于kubeadm创建新的token(问题分析)

    这篇文章主要介绍了使用golang脚本基于kubeadm创建新的token(问题分析),本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-10-10
  • Golang语言的跨平台UI工具包fyne使用详解

    Golang语言的跨平台UI工具包fyne使用详解

    这篇文章主要为大家介绍了Golang语言的跨平台UI工具包fyne使用详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-12-12
  • Go语言流程控制详情

    Go语言流程控制详情

    这篇文章主要介绍了Go语言流程控制详情,流程控制包含分三大类:条件判断,循环控制和无条件跳转。下面关于更多相关内容需要的小伙伴可以参考一下
    2022-03-03
  • 在Mac OS上安装Go语言编译器的方法

    在Mac OS上安装Go语言编译器的方法

    这篇文章主要介绍了在Mac OS上安装Go语言编译器的方法,Docker的兴起使得Go近来人气大幅攀升,需要的朋友可以参考下
    2015-10-10
  • 使用Go语言实现敏感词过滤功能

    使用Go语言实现敏感词过滤功能

    敏感词过滤,算是一个比较常见的功能,尤其是在内容、社交类应用中更是如此,本文介绍如何使用Go语言实现简单的敏感词过滤功能,文中通过代码示例介绍的非常详细,需要的朋友可以参考下
    2023-12-12
  • Go语言学习之将mp4通过rtmp推送流媒体服务的实现方法

    Go语言学习之将mp4通过rtmp推送流媒体服务的实现方法

    对音视频一直是小白,决定沉下心来,好好研究一下音视频知识,下面这篇文章主要给大家介绍了关于Go语言学习之将mp4通过rtmp推送流媒体服务的实现方法,需要的朋友可以参考下
    2022-12-12
  • 使用gopkg.in/yaml.v3 解析YAML数据详解

    使用gopkg.in/yaml.v3 解析YAML数据详解

    这篇文章主要为大家介绍了使用gopkg.in/yaml.v3 解析YAML数据示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-09-09

最新评论