Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[pref]uuid生成性能改进 #42

Merged
merged 1 commit into from
Dec 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 10 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@
- [x] 字符串相关操作
- Clean 清理字符串,将其中的特殊字符(括号、标点符号、转义字符等等)一律转换成下划线
- JoinElements 将任意基本类型的数组使用英文逗号拼接成一个字符串
- B2S byte切片转为string
- S2B string转为byte切片
- B2S byte切片转为string,不使用常规的强转方法,直接引用内存地址转换,性能非常高
- S2B string转为byte切片,不使用常规的强转方法,直接引用内存地址转换,性能非常高
- MaskChineseName 中文姓名脱敏
- MaskChineseNameEx 中文姓名脱敏扩展方法,可指定脱敏位
- MaskChineseMobile 中国手机号脱敏
Expand All @@ -42,7 +42,7 @@
- MaskChineseIdCard64 中国身份证号脱敏,MaskChineseMobile简化版,保留前6位后4位
- MaskChineseIdCard11 中国身份证号脱敏,MaskChineseMobile简化版,保留前1位后1位
- MaskAnyString 任意字符串脱敏,可指定左侧保留几个字符、右侧保留几个字符
- Masker 更强大的字符串脱敏工具💊,有多个选项可以用于实现您的脱敏需求,位于子包`kg_str`中
- Masker 更强大的字符串脱敏综合工具💊,有多个选项可以用于实现您的脱敏需求,能够将任意敏感信息(身份证号、手机号、地址、银行卡号等等)脱敏,位于子包`kg_str`中
- [x] 本地缓存相关操作
- Set 设置缓存项,支持仅设置缓存,也支持同时给缓存添加一个过期时间
- Get 获得缓存内容
Expand All @@ -68,9 +68,9 @@
- JoinStructsField 将任意结构体切片中的指定字段的值使用英文逗号拼接成一个字符串,例如:用户列表中,所有用户ID拼成一个字符串
- PickStructsField 将任意结构体切片中的指定字段的值提取出来形成一个保持原类型的数组,例如:用户列表中,所有用户ID提取成一个用户ID数组
- SliceGroupBy 将任何结构体切片切片中按指定字段的值提取出来进行分组,形成一个Map,例如对用户按类型分组,类型的值为Map的key,对应类型的所有用户集合为Map的Value
- CopyFields 复制结构体实例字段值到目标结构体实例,类似于Java中的BeanUtils.copyProperties(src, dst)工具类
- CopyFields 复制结构体实例字段值到目标结构体实例,类似于Java中的BeanUtils.copyProperties(src, dst)工具类,这个非常实用,我再也不用写几十行的两个结构体实例赋值的代码了
- [x] 雪花算法
- 通用实现方法,初始化一次,到处随时获得ID,多goroutine并发安全
- 通用实现方法,在程序启动的时候调用`InitSnowflake(workerId int64, dataCenterId int64) (err error)`初始化一次,到处随时使用方法`SnowflakeId() int64`和`GetSnowflakeId[T string | int64]() (id T)`获得ID,并发安全
- [x] UUID 高性能UUID
- Uuid 通用方法,自带缓冲池,不需要初始化,随时获得ID,多goroutine并发安全
- SimpleUuid 去除横线方法,自带缓冲池,不需要初始化,到处随时获得ID,多goroutine并发安全,推荐👍👍👍
Expand All @@ -93,7 +93,7 @@ go get -u github.com/ccpwcn/kgo

# 4. 使用方法

使用方法非常简单,kgo作为包名,后面跟着函数名就可以了,比如`kgo.SimpleUuid()`就能生成一个ID。所有函数都是kgo下,目前没有二级包。
使用方法非常简单,kgo作为包名,后面跟着函数名就可以了,比如`kgo.SimpleUuid()`就能生成一个ID。

具体请查看单元测试,那里就是测试代码,或者直接查看源码,都是非常简单的引用类,后面东西多了,复杂了,我再加上专门的使用说明文档吧。

Expand Down Expand Up @@ -266,9 +266,11 @@ ok github.com/ccpwcn/kgo 474.448s
- 压力测试,生成500万个标准UUID形式的ID耗时约54秒,高并发每秒可生成约92万个标准ID。
- 压力测试,生成500万个无连接线的最简唯一ID耗时约52秒,高并发每秒可生成96万个无连接线的简单ID。
- 不带连接线的简单ID比标准UUID形式的ID性能强约10%。
- 在性能测试中,加入了`sync.Map`用于保证海量的ID仍然是唯一的,不会重复。在实践中,如果没有这个,生成ID的速度可以更快,所以能胜任任何场景了
- 在性能测试中,加入了`sync.Map`用于保证海量的ID仍然是唯一的,不会重复。在实践中,如果没有这个,生成ID的速度可以更快,如果程序运行在热代码状态,性能还能更进一步,所以我认为它能胜任99.99%的业务场景了

🍓请允许自我吹嘘一下:以如此强悍的性能生成唯一ID,太牛了,以后就它了!
> 剩下那0.01%的业务场景怎么办?也好办,搞多个后台服务,配置不同的workerId和dataCenterId,搞成分布式环境下引用本库生成雪花算法UUID,或者将引用本包中的UUID生成方法的程序布在不同的机器上,那么它们的硬件特征、硬件时钟不同,随机结果就不会重复。因为根据UUID算法的重复性分析研究结果,假如每秒产生10亿笔UUID,100年后只产生一次重复的机率是50%。如果地球上每个人都各有6亿笔UUID,发生一次重复的机率是50%。所以,担心什么?放心用吧。

🍓🍓🍓请允许自我吹嘘一下:如此强悍生成唯一ID工具包,太牛了,我已在大规模生产环境中用起来了!

# 鸣谢
UUID的实现借鉴学习了 https://github.com/google/uuid
4 changes: 2 additions & 2 deletions uuid.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,14 @@ func Uuid() string {
uuid := newRandomFromPool()
var buf [36]byte
encodeHex(buf[:], uuid)
return string(buf[:])
return B2S(buf[:])
}

func SimpleUuid() string {
uuid := newRandomFromPool()
var buf [32]byte
encodeHexShort(buf[:], uuid)
return string(buf[:])
return B2S(buf[:])
}

func newRandomFromPool() UUID {
Expand Down