You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kotlin中如何高效统计SortedMap的重复值数量,降低内存开销

现有代码的隐含优化点

你当前的实现除了HashSet的内存开销外,还有一处不必要的内存浪费:filter操作会生成一个临时List存储所有符合条件的条目,百万级数据下这部分开销完全可以避免,直接使用count的谓词判断即可,优化后代码如下:

val uniqueValueSet = hashSetOf<String>()
val numDuplicates = cache.count { !uniqueValueSet.add(it.value) }

这行改动可以直接省掉和重复值数量相等的内存占用,不需要额外逻辑成本。

精确统计的最优方案

如果需要100%准确的统计结果,可根据你的场景二选一:

  • 场景:值重复率较高
    可以用频率统计字典替代HashSet,最终通过频率计算重复数,内存占用和HashSet方案一致,但CPU开销更低:
    var numDuplicates = 0
    val freqMap = hashMapOf<String, Int>()
    cache.values.forEach { value ->
        val count = freqMap.getOrDefault(value, 0)
        if (count >= 1) {
            numDuplicates++
        }
        freqMap[value] = count + 1
    }
    
  • 场景:内存极端受限,允许少量CPU和IO开销
    利用排序后重复值连续的特性,先将所有值导出做外部归并排序,再遍历排序后的结果统计重复数,整个过程只需要占用几MB的排序缓冲区内存,不需要存储全量不同值,适合内存不足的离线统计场景。
超大规模数据下的近似统计方案

如果业务允许2%以内的统计误差,推荐使用HyperLogLog算法实现,仅需要12KB的固定内存即可完成数百万甚至数十亿级数据的不同值计数,最终通过「总条目数 - 不同值数量」得到重复值总数,内存开销几乎可以忽略。
Kotlin/Java环境可以直接使用Guava提供的HyperLogLog实现,示例逻辑如下:

val hll = HyperLogLog(10) // 精度参数,数值越大误差越小,内存占用越高
cache.values.forEach { hll.offer(it) }
val approxUniqueCount = hll.cardinality()
val approxDuplicates = cache.size - approxUniqueCount

内容的提问来源于stack exchange,提问作者hermanjakobsen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 11:15:03