XCollect

package
v0.0.9 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 25, 2025 License: MIT Imports: 5 Imported by: 1

README

XCollect

Reference Release Report DeepWiki

XCollect 提供了一组集合类型数据的工具函数集,包括数组操作工具和线程安全的字典工具。

功能特性

  • 数组工具:泛型数组操作函数,支持查找、删除等常用功能,适用于任意可比较类型
  • 字典工具:线程安全的字典结构,支持高效的读写操作和并发遍历,兼具性能与易用性

使用手册

1. 数组工具
1.1 按值查找

使用 IndexContains 函数进行精确值匹配:

arr := []int{1, 2, 3, 4, 5}

// 查找元素索引
idx := XCollect.Index(arr, 3)        // 返回 2

// 检查元素是否存在
exists := XCollect.Contains(arr, 3)   // 返回 true
1.2 条件查找

使用函数作为查找条件,实现灵活的查找逻辑:

// 查找第一个偶数
idx := XCollect.Index(arr, func(x int) bool {
    return x%2 == 0
})                                    // 返回 1(元素2的索引)
1.3 元素删除

提供两种删除方式:按值删除和按索引删除:

// 按值删除(删除所有匹配的元素)
arr = XCollect.Remove(arr, 3)         // 返回 [1, 2, 4, 5]

// 按索引删除(删除指定位置的元素)
arr = XCollect.Delete(arr, 1)         // 返回 [1, 4, 5]
1.4 元素添加

支持在数组末尾追加或在指定位置插入元素:

// 在末尾追加元素
arr = XCollect.Append(arr, 6)         // 返回 [1, 4, 5, 6]

// 在指定位置插入元素
arr = XCollect.Insert(arr, 1, 2)      // 返回 [1, 2, 4, 5, 6]
2. 字典工具
2.1 基本操作

创建和基本的增删改查操作:

// 创建一个新的线程安全Map
map := XCollect.NewMap()

// 存储键值对
map.Store("key1", 100)
map.Store("key2", 200)

// 读取值
value, exists := map.Load("key1")  // 返回 100, true

// 删除键值对
map.Delete("key1")

// 清空所有键值对
map.Clear()
2.2 遍历操作

两种遍历方式,适用于不同的场景:

// 基础遍历
map.Range(func(key, value any) bool {
    fmt.Printf("键: %v, 值: %v\n", key, value)
    return true  // 返回false可以提前终止遍历
})

// 并发遍历(适用于大数据)
map.RangeConcurrent(func(chunk int, key, value any) bool {
    fmt.Printf("分片: %d, 键: %v, 值: %v\n", chunk, key, value)
    return true  // 返回false可以提前终止所有协程的遍历
}, func(chunk int) {
    fmt.Printf("开始并发遍历,分片数量: %d\n", chunk)
})

常见问题

1. XCollect 数组工具支持哪些数据类型?

支持所有满足 comparable 约束的类型,包括:

  • 基本类型:整数、浮点数、字符串等
  • 复合类型:结构体(需要可比较)、指针等 注意:
  • 使用泛型避免接口转换开销
  • 就地修改数组减少内存分配
  • 使用 append 优化切片操作
2. XCollect 字典工具的性能及适用场景?
2.1 读写操作

📊 XCollect.Map vs sync.Map 性能对照表(数据量 10000):

Map 类型 CPU 核数 操作次数 (N) 平均时间 (ns/op) 内存分配 (B/op) 分配次数 (allocs/op)
XCollect.Map 1 17799663 65.10 ns/op 23 B/op 2 allocs/op
XCollect.Map 2 23778950 48.38 ns/op 23 B/op 2 allocs/op
XCollect.Map 4 28436152 40.58 ns/op 23 B/op 2 allocs/op
XCollect.Map 8 36565410 35.37 ns/op 23 B/op 2 allocs/op
XCollect.Map 16 36156556 32.37 ns/op 23 B/op 2 allocs/op
XCollect.Map 32 37887278 32.13 ns/op 23 B/op 2 allocs/op
sync.Map 1 19024426 56.36 ns/op 23 B/op 1 allocs/op
sync.Map 2 31349271 37.84 ns/op 23 B/op 1 allocs/op
sync.Map 4 56206615 21.92 ns/op 23 B/op 1 allocs/op
sync.Map 8 91515728 14.89 ns/op 23 B/op 1 allocs/op
sync.Map 16 100000000 11.17 ns/op 23 B/op 1 allocs/op
sync.Map 32 132207163 9.795 ns/op 23 B/op 1 allocs/op

数据分析:

  1. 两者都表现出良好的扩展性,CPU 核数越多,ns/op 越低,但 sync.Map 在多核下的性能提升更为显著,尤其是 8 核 及以上时表现优越。
  2. XCollect.Map 尽管平均性能逊于 sync.Map,但在低并发场景下(1–4 核)仍表现出较强竞争力,平均时延接近或略优。
  3. 两者单位操作的内存占用相同(23 B/op),sync.Map 每次操作只产生一次内存分配,而 XCollect.Map 每次产生两次分配,可能影响 GC 压力。
2.2 遍历操作

📊 XCollect.Map Range vs XCollect.Map Concurrent Range vs sync.Map Range vs map range 性能对照表(数据量 100000):

Map 类型 CPU 核数 操作次数 (N) 平均时间 (ns/op) 内存分配 (B/op) 分配次数 (allocs/op)
XCollect.Map 1 10000 106382 ns/op 0 B/op 0 allocs/op
XCollect.Map 2 12199 104806 ns/op 0 B/op 0 allocs/op
XCollect.Map 4 10000 101121 ns/op 0 B/op 0 allocs/op
XCollect.Map 8 10000 102604 ns/op 0 B/op 0 allocs/op
XCollect.Map 16 10000 100402 ns/op 0 B/op 0 allocs/op
XCollect.Map 32 10000 105550 ns/op 0 B/op 0 allocs/op
XCollect.Map(Concurrent) 1 11443 110427 ns/op 2068 B/op 66 allocs/op
XCollect.Map(Concurrent) 2 19808 63128 ns/op 2068 B/op 66 allocs/op
XCollect.Map(Concurrent) 4 30472 42135 ns/op 2068 B/op 66 allocs/op
XCollect.Map(Concurrent) 8 34371 41602 ns/op 2068 B/op 66 allocs/op
XCollect.Map(Concurrent) 16 29734 42611 ns/op 2068 B/op 66 allocs/op
XCollect.Map(Concurrent) 32 27742 41233 ns/op 2068 B/op 66 allocs/op
sync.Map 1 584 2023889 ns/op 0 B/op 0 allocs/op
sync.Map 2 589 2018034 ns/op 0 B/op 0 allocs/op
sync.Map 4 588 2066907 ns/op 0 B/op 0 allocs/op
sync.Map 8 566 2082428 ns/op 0 B/op 0 allocs/op
sync.Map 16 572 2169874 ns/op 0 B/op 0 allocs/op
sync.Map 32 639 2033276 ns/op 0 B/op 0 allocs/op
map 1 2276 527344 ns/op 0 B/op 0 allocs/op
map 2 2293 523724 ns/op 0 B/op 0 allocs/op
map 4 2408 517579 ns/op 0 B/op 0 allocs/op
map 8 2262 536811 ns/op 0 B/op 0 allocs/op
map 16 2329 528598 ns/op 0 B/op 0 allocs/op
map 32 2270 533023 ns/op 0 B/op 0 allocs/op

数据分析:

  1. XCollect.Map 普通遍历在全核数范围内稳定在 100μs 左右,非常稳定且零分配。
  2. XCollect.Map 并发遍历利用多核并发(4–8 核效率最优),可将遍历时间降到约 41μs(~2.4 倍加速),但带来小量额外分配(每次遍历约 2KB 内存、66 次分配)。
  3. sync.Map 遍历性能较差差,平均遍历耗时超过 2ms(2000μs)
  4. map 的遍历速度约在 500μs 水平,低于 Sync.Map,但相较于 XCollect.Map 没有优势且不支持并发。
2.3 适用场景
  1. XCollect.Map:高并发、大数据、读多写少。
  2. sync.Map:高并发、数据可控、读写均衡。
  3. map:低并发、数据可控、读写均衡。

更多问题,请查阅问题反馈

项目信息

Documentation

Overview

XCollect 提供了一组集合类型数据的工具函数集,包括数组操作工具和线程安全的字典工具。

功能特性

- 数组工具:泛型数组操作函数,支持查找、删除、插入等常用功能,适用于任意可比较类型

- 字典工具:线程安全的泛型 Map,支持高效的读写操作和顺序/并发遍历,兼具性能与易用性

使用手册

1. 数组工具

1.1 按值查找

arr := []int{1, 2, 3, 4, 5}
idx := XCollect.Index(arr, 3)        // 返回 2
exists := XCollect.Contains(arr, 3)   // 返回 true

1.2 条件查找

idx = XCollect.Index(arr, func(x int) bool {
    return x%2 == 0
})                                    // 返回第一个偶数的索引 1

1.3 元素删除

arr = XCollect.Remove(arr, 3)         // 返回 [1, 2, 4, 5]
arr = XCollect.Delete(arr, 1)         // 返回 [1, 4, 5]

1.4 元素添加

arr = XCollect.Append(arr, 6)         // 返回 [1, 4, 5, 6]
arr = XCollect.Insert(arr, 1, 2)      // 返回 [1, 2, 4, 5, 6]

2. 字典工具

2.1 基本操作

map := XCollect.NewMap()
map.Store("key1", 100)
map.Store("key2", 200)
value, exists := map.Load("key1")  // 返回 100, true
map.Delete("key1")
map.Clear()

2.2 遍历操作

map.Range(func(key, value any) bool {
    fmt.Printf("键: %v, 值: %v\n", key, value)
    return true
})

map.RangeConcurrent(func(chunk int, key, value any) bool {
    fmt.Printf("分片: %d, 键: %v, 值: %v\n", chunk, key, value)
    return true
}, func(chunk int) {
    fmt.Printf("开始并发遍历,分片数量: %d\n", chunk)
})

更多信息请参考模块文档。

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Append

func Append[T comparable](arr []T, ele T) []T

Append 将元素添加到数组末尾,返回添加元素后的新数组。

func Contains

func Contains[T comparable](arr []T, ele any) bool

Contains 检查指定元素是否存在于数组中。参数 ele 可以是具体值或条件函数 func(T) bool。 如果元素存在返回 true,否则返回 false。

func Delete

func Delete[T comparable](arr []T, idx int) []T

Delete 删除数组中指定索引位置的元素。如果索引无效或数组为空,返回原数组。

func Index

func Index[T comparable](arr []T, ele any) int

Index 在数组中查找指定元素,返回其第一次出现的索引位置。如果未找到或数组为空,返回 -1。 参数 ele 可以是具体值或判断函数 func(T) bool。

func Insert

func Insert[T comparable](arr []T, idx int, ele T) []T

Insert 在数组的指定位置插入元素。如果索引无效或数组为空,返回原数组。

func Remove

func Remove[T comparable](arr []T, ele any) []T

Remove 从数组中移除所有指定的元素。参数 ele 可以是具体值或条件函数 func(T) bool。 返回移除元素后的新数组。

Types

type Map added in v0.0.3

type Map struct {
	// contains filtered or unexported fields
}

Map 提供一个线程安全的键值映射结构。 内部使用分段锁实现,将数据分成多个分片,每个分片有独立的锁,减少锁竞争。 键值存储采用 map 用于快速索引,切片用于遍历优化。 适用于高并发读写场景,大数据遍历性能优于标准库的 sync.Map。

func NewMap added in v0.0.3

func NewMap() *Map

NewMap 创建并返回一个新的 Map 实例。 返回的 Map 实例是未初始化的,将在首次使用时延迟初始化。

func (*Map) Clear added in v0.0.3

func (m *Map) Clear()

Clear 清除所有键值对。 该方法会重置所有分片的数据,但保留分片结构,适用于需要重用 Map 的场景。 该操作是线程安全的,对每个分片使用写锁保护。

func (*Map) Delete added in v0.0.3

func (m *Map) Delete(key any)

Delete 删除指定 key 及其对应的值。 若 key 存在,删除并重排内部切片以保持数据紧凑;否则不做处理。 该操作是线程安全的,使用写锁保护。

func (*Map) Load added in v0.0.3

func (m *Map) Load(key any) (value any, ok bool)

Load 返回指定 key 对应的值。 如果 key 存在,则返回对应的值和 true,否则返回 nil 和 false。 该操作是线程安全的,使用读锁保护。

func (*Map) LoadAndDelete added in v0.0.3

func (m *Map) LoadAndDelete(key any) (value any, loaded bool)

LoadAndDelete 返回指定 key 对应的值并将其从映射中删除。 value 是 key 对应的值,如果 key 不存在则为 nil。 loaded 表示 key 是否存在,true 表示 key 存在并已删除,false 表示 key 不存在。 该操作是线程安全的,使用写锁保护。

func (*Map) LoadOrStore added in v0.0.3

func (m *Map) LoadOrStore(key any, value any) (actual any, loaded bool)

LoadOrStore 返回指定 key 的值,若 key 不存在则写入默认值。 actual 表示实际存储的值(已存在的或新写入的)。 loaded 表示 key 已存在,false 表示 key 不存在并已写入新值。 该操作是线程安全的,使用写锁保护。

func (*Map) Range added in v0.0.3

func (m *Map) Range(process func(key any, value any) bool)

Range 遍历所有键值对,并调用用户提供的 process 函数。 process 是处理函数,接收 key 和 value 作为参数,返回布尔值,如果 process 返回 false,则提前中断遍历。 该操作是线程安全的,对每个分片使用读锁保护。 注意:遍历过程中不应修改 Map 内容,否则可能导致不可预期的结果。

func (*Map) RangeConcurrent added in v0.0.3

func (m *Map) RangeConcurrent(process func(chunk int, key any, value any) bool, worker ...func(int))

RangeConcurrent 并发遍历所有键值对,内部根据分片数量自动确定协程数量。 process 是处理函数,接收分片索引、key 和 value 作为参数,返回布尔值,如果 process 返回 false,则通知所有协程终止遍历。 worker 是可选的回调函数,在启动并发处理前调用,接收分片数量作为参数。 该操作是线程安全的,对每个分片使用读锁保护,适用于需要并行处理大量数据的场景,可显著提高处理速度。 注意:遍历过程中不应修改 Map 内容,否则可能导致不可预期的结果。

func (*Map) Store added in v0.0.3

func (m *Map) Store(key any, value any)

Store 设置指定 key 的值。 如果 key 已存在,则更新其值;否则插入新的键值对。 该操作是线程安全的,使用写锁保护。

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL