golang高效内存近似计数统计插件库count-min-log的使用

Golang高效内存近似计数统计插件库count-min-log的使用

Count-Min-Log简介

Count-Min-Log Sketch是一种改进的低频事件平均相对误差的计数算法。Count-Min Sketch是广泛用于大规模处理中近似事件计数的算法,但原始版本在处理低频项(如文本挖掘相关任务)时存在一些不足。Count-Min-Log使用基于对数的近似计数器代替线性计数器,在保持相同内存占用的同时改善了CMS的平均相对误差。

示例用法

下面是一个完整的Go语言示例,展示如何使用count-min-log库:

package main

import (
	"fmt"
	"github.com/seiflotfy/count-min-log" // 导入count-min-log库
)

func main() {
	// 创建一个默认的Count-Min-Log Sketch
	sk, err := cml.NewDefaultSketch()
	if err != nil {
		panic(err)
	}

	// 增加计数
	sk.IncreaseCount([]byte("scott pilgrim")) // 计数+1
	sk.IncreaseCount([]byte("scott pilgrim")) // 计数+1
	sk.IncreaseCount([]byte("ramona flowers")) // 计数+1

	// 查询频率
	fmt.Println("scott pilgrim count:", sk.Frequency([]byte("scott pilgrim"))) // 输出: 2
	fmt.Println("ramona flowers count:", sk.Frequency([]byte("ramona flowers"))) // 输出: 1
	fmt.Println("knives chau count:", sk.Frequency([]byte("knives chau"))) // 输出: 0 (未计数的项)
}

主要功能说明

  1. NewDefaultSketch() - 创建一个默认配置的Count-Min-Log Sketch
  2. IncreaseCount([]byte) - 增加指定项的计数
  3. Frequency([]byte) - 查询指定项的近似计数

注意事项

  1. Count-Min-Log提供的是近似计数,不是精确计数
  2. 对于低频项的计数相对误差更小
  3. 内存占用固定,适合大规模数据处理

这个库特别适合需要统计大量不同项出现次数但对精度要求不是绝对精确的场景,如网络流量分析、日志分析等大数据处理应用。


更多关于golang高效内存近似计数统计插件库count-min-log的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于golang高效内存近似计数统计插件库count-min-log的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


Golang高效内存近似计数统计插件库count-min-log的使用

count-min-log是一个基于Count-Min Sketch算法的Golang库,用于高效地进行近似计数统计。它特别适合处理大数据流中的频率统计问题,能够在有限内存下提供高效的近似计数功能。

基本概念

Count-Min Sketch是一种概率数据结构,用于:

  • 估计数据流中元素的频率
  • 使用固定大小的内存
  • 提供近似结果(可能高估但不会低估)

count-min-log是Count-Min Sketch的一种变体,在内存使用上更加高效。

安装

go get github.com/seiflotfy/count-min-log

基本使用

初始化

package main

import (
	"fmt"
	"github.com/seiflotfy/count-min-log"
)

func main() {
	// 创建一个新的Count-Min-Log实例
	// 参数:期望的误差率(epsilon)和误差概率(delta)
	cml, err := countminlog.NewForEpsilonDelta(0.01, 0.01)
	if err != nil {
		panic(err)
	}
	
	// 添加元素
	cml.Add([]byte("apple"))
	cml.Add([]byte("banana"))
	cml.Add([]byte("apple"))
	cml.Add([]byte("apple"))
	cml.Add([]byte("orange"))
	
	// 查询计数
	fmt.Println("apple count:", cml.Count([]byte("apple")))    // ≈3
	fmt.Println("banana count:", cml.Count([]byte("banana")))  // ≈1
	fmt.Println("orange count:", cml.Count([]byte("orange")))  // ≈1
	fmt.Println("pear count:", cml.Count([]byte("pear")))      // ≈0
}

合并多个实例

func mergeExample() {
	cml1, _ := countminlog.NewForEpsilonDelta(0.01, 0.01)
	cml2, _ := countminlog.NewForEpsilonDelta(0.01, 0.01)
	
	for i := 0; i < 100; i++ {
		cml1.Add([]byte("apple"))
	}
	
	for i := 0; i < 50; i++ {
		cml2.Add([]byte("apple"))
	}
	
	err := cml1.Merge(cml2)
	if err != nil {
		panic(err)
	}
	
	fmt.Println("merged apple count:", cml1.Count([]byte("apple"))) // ≈150
}

序列化和反序列化

func serializationExample() {
	cml, _ := countminlog.NewForEpsilonDelta(0.01, 0.01)
	cml.Add([]byte("test"))
	
	// 序列化
	data, err := cml.GobEncode()
	if err != nil {
		panic(err)
	}
	
	// 反序列化
	newCml := &countminlog.CountMinLog{}
	err = newCml.GobDecode(data)
	if err != nil {
		panic(err)
	}
	
	fmt.Println("deserialized count:", newCml.Count([]byte("test"))) // ≈1
}

高级用法

自定义参数

func customParameters() {
	// 直接指定宽度和深度
	cml, err := countminlog.New(5, 10)
	if err != nil {
		panic(err)
	}
	
	// 或者通过期望的容量和误差率计算
	cml2, err := countminlog.NewForCapacity(10000, 0.01)
	if err != nil {
		panic(err)
	}
}

批量添加元素

func batchAdd() {
	cml, _ := countminlog.NewForEpsilonDelta(0.01, 0.01)
	
	items := [][]byte{
		[]byte("item1"),
		[]byte("item2"),
		[]byte("item1"),
		[]byte("item3"),
	}
	
	for _, item := range items {
		cml.Add(item)
	}
}

性能考虑

  1. 内存使用:count-min-log比传统Count-Min Sketch更节省内存
  2. 误差率:epsilon和delta值越小,精度越高,但内存消耗越大
  3. 并发安全:默认不是并发安全的,需要自己加锁
import "sync"

type SafeCML struct {
	*countminlog.CountMinLog
	mu sync.Mutex
}

func (s *SafeCML) Add(item []byte) {
	s.mu.Lock()
	defer s.mu.Unlock()
	s.CountMinLog.Add(item)
}

func (s *SafeCML) Count(item []byte) uint64 {
	s.mu.Lock()
	defer s.mu.Unlock()
	return s.CountMinLog.Count(item)
}

适用场景

  1. 高频数据流中的元素计数
  2. 内存有限但需要统计大量不同元素
  3. 可以接受近似结果的场景
  4. 分布式系统中需要合并统计结果

注意事项

  1. 结果可能会有误差(总是正偏差)
  2. 无法删除已添加的元素
  3. 需要根据应用场景调整epsilon和delta参数

count-min-log是一个在内存效率和计数准确性之间取得良好平衡的库,非常适合大数据场景下的近似计数需求。

回到顶部