Java:优化哈希集以进行大规模重复检测

2023-11-24

我正在开发一个项目,需要处理大量推文;目标是在处理重复项时删除它们。我有推文 ID,它们以以下格式的字符串形式出现"166471306949304320"

我一直在使用HashSet<String>为此,暂时效果很好。但当我达到大约 1000 万个项目时,我彻底陷入困境,最终出现 GC 错误,大概是由于重新哈希造成的。我尝试定义更好的尺寸/负载

tweetids = new HashSet<String>(220000,0.80F);

这让它走得更远,但速度仍然极其缓慢(大约 1000 万,处理时间是原来的 3 倍)。我该如何优化这个?考虑到我对最后应该有多少项有一个大致的了解(在本例中,大约 20-2200 万),我是否应该创建一个仅重新散列两次或三次的 HashSet,或者这样的开销设置会招致太多时间处罚吗?如果我不使用字符串,或者定义不同的 HashCode 函数(在这种情况下是字符串的特定实例,我不知道该怎么做),事情会更好吗?这部分的实现代码如下。

tweetids = new HashSet<String>(220000,0.80F); // in constructor
duplicates = 0;
...
// In loop: For(each tweet)
String twid = (String) tweet_twitter_data.get("id");
// Check that we have not processed this tweet already
if (!(tweetids.add(twid))){
    duplicates++;
    continue; 
}

SOLUTION

感谢您的建议,我解决了这个问题。问题在于哈希表示所需的内存量;第一的,HashSet<String>简直是巨大且不必要的,因为String.hashCode()对于这个规模来说是过高的。接下来我尝试了 Trie,但它在条目数超过 100 万时就崩溃了;重新分配数组是有问题的。我用了一个HashSet<Long>效果更好,几乎成功了,但速度下降了,最终在处理的最后一段(大约 1900 万)崩溃了。解决方案来自于脱离标准库并使用Trove。它完成 2200 万条记录比根本不检查重复项要快几分钟。最终的实现很简单,如下所示:

import gnu.trove.set.hash.TLongHashSet;
...
    TLongHashSet tweetids; // class variable
... 
    tweetids = new TLongHashSet(23000000,0.80F); // in constructor
...
    // inside for(each record)
    String twid = (String) tweet_twitter_data.get("id");
    if (!(tweetids.add(Long.parseLong(twid)))) {
        duplicates++;
        continue; 
    }

您可能想要超越 Java 集合框架。我已经完成了一些内存密集型处理,您将面临几个问题

  1. 大型哈希图和哈希集的桶数将是 造成大量开销(内存)。您可以通过使用来影响这一点 某种自定义哈希函数和模数,例如50000
  2. Java 中的字符串使用 16 位字符表示。对于大多数脚本,您可以通过使用 utf-8 编码的字节数组将其减半。
  3. HashMap 通常是相当浪费的数据结构,而 HashSet 基本上只是这些数据结构的薄包装。

鉴于此,看看 trove 或 guava 的替代品。另外,你的 id 看起来像 long。这些是 64 位的,比字符串表示形式小很多。

您可能需要考虑的另一种选择是使用布隆过滤器(番石榴有一个不错的实现)。布隆过滤器会告诉您某些东西是否绝对不在集合中,并且以合理的确定性(小于 100%)告诉您某些东西是否包含在集合中。与一些基于磁盘的解决方案(例如数据库、mapdb、mecached...)相结合应该可以很好地工作。您可以缓冲传入的新 ID,批量写入它们,并使用布隆过滤器检查是否需要在数据库中查找,从而在大多数情况下避免昂贵的查找。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java:优化哈希集以进行大规模重复检测 的相关文章

随机推荐

  • 从 Crashlytics SDK 迁移到 Fabric 后出现构建错误

    最近 我们已将组织的 Crashlytics 帐户升级到 Fabric 我正在尝试在现有应用程序中用新的 Fabric SDK 替换旧的 Crashlytics SDK 我已经关注了迁移说明 而且基本上很轻松 除了我现在在尝试编译时收到构建
  • 将变量传递给带有字边界的 RegExp

    我必须传递变量的 RegExp 值并指向字边界 我有一个字符串要检查它是否包含变量值 我不知道如何将变量值和单词边界属性传递给正则表达式 所以像这样 var sa Sample var re new RegExp b sa alert re
  • Android 应用程序永远不会自动更新

    我在 Play 商店中有一个有点不寻常的 Android 应用程序 它在专用设备上 24 7 运行 它收集传感器数据 并不意味着在用于其他用途的手机上运行 我希望该应用程序能够在没有用户交互的情况下自动更新 但这似乎永远不会发生 为什么会这
  • 删除javascript中的第一个孩子

    我正在尝试删除第一个li in an ol使用 DOMremoveChild 但由于某种原因它不起作用 这是我的 JavaScript document getElementById queue removeChild document g
  • CrystalReports ReportDocument 数据库连接内存泄漏

    我过去几天一直在研究这个问题 但似乎无法弄清楚 我有一个c WinForms应用程序使用ReportDocument加载报表并将其放入 Crystal Report Viewer 中 以便用户可以预览它 目的是预览不同的统计数据 并且表单永
  • C++11 中局部静态变量初始化是线程安全的吗? [复制]

    这个问题在这里已经有答案了 我知道这是一个经常被问到的问题 但由于有很多变体 我想重申一下 并希望能得到一个反映当前状态的答案 就像是 Logger g logger static Logger lg return lg 变量 lg 的构造
  • setDragImage 不工作 - Java 7

    我正在尝试设置代码 以便用户可以从 JTable 拖动到 JList 并使用 TransferHandler 中的 Java 7 函数 setDragImage 自定义拖动图像 我在java教程网站上找到了一个示例 他们在其中教授Drag
  • SyntaxError:未终止的字符串文字 标记在字符串变量中不起作用

    请看我的代码 var id 1 var htmlText div ul class rtabs ul div class panel container div div div div div style display none Blah
  • 按嵌套对象的一个​​属性对对象数组进行排序

    我需要通过对象属性之一的一个属性来比较对象数组 我在做 List
  • 如何将 accdb 转换为 postgres 数据库

    我需要使用 accdb 数据库 为此需要将其导入 PostgreSQL 我相信这将是一个简单而直接的问题 我预计它已经解决了 但我没有找到一个简单的解决方案 我要补充一点 我无权访问 Access 笑 并且我的解决方案松散地依赖于此 如果那
  • 从 .crt 和 .key 文件创建 .jks 是否可能

    我向权威机构申请了 SSL 证书 首先 我在计算机上创建了一个 csr 和一个 key 文件并保存了它们 我发送了 csr 并取回了 crt 文件和我安装在服务器上的其他文件 对于具有 SSL 连接的 Apache 服务器来说 一切正常 但
  • OpenCart:如何准确填充 oc_category_path

    我使用在线服务将数据从其他电子商务网站传输到OpenCart一切似乎都已正确转移 然而 产品类别存在一个问题 类别已转移至oc category桌子 但是 看起来还有另一张表叫做oc category path如果我希望能够在管理员中编辑我
  • 使用 OpenGL ES 2.0 进行 GPGPU 编程

    我正在尝试在 GPU 上进行一些图像处理 例如中值 模糊 亮度等 总体思路是做类似的事情这个框架来自 GPU 宝石 1 我能够编写 GLSL 片段着色器来处理像素 因为我一直在效果设计器应用程序中尝试不同的东西 然而我不确定我应该如何完成任
  • .NET 的哪些部分在 iPhone 开发者的 Monotouch 中不可用?

    哪些键绑定未包含在内 您可以在以下位置找到 MonoTouch 的完整限制列表 Xamarin MonoTouch 中不可用的 NET 功能的简短列表 动态语言运行时 DLR 通用虚拟方法 泛型类型中的 P 调用 作为字典键的值类型 系统
  • 带索引变量的 Sympy 求和

    我尝试使用带有索引变量的 Sum 创建一个 sympy 表达式 如前所述here但是 我无法对该表达式进行羔羊化并给出一个数组来计算总和 这不可能吗 也许像这样 s Sum Indexed x i i 1 3 f lambda x Subs
  • 如何在 Rails 中设置 url 助手的默认主机?

    我想做这样的事情 config default host www subdomain example com 在我的一些配置文件中 这样object url帮手 ActionView Helpers UrlHelper 生成以以下内容开头的
  • 高效的算法可根据特定目标组成有效的表达式

    该问题表述为 给定一个仅包含数字 0 9 和一个目标值的字符串 返回通过在数字之间添加一些二元运算符 或 创建的所有表达式 以便它们计算为目标值 在某些情况下 可能没有任何二元运算符可以创建有效的表达式 在这种情况下 函数应返回空数组 新表
  • 如何在struct的方法中设置和获取字段

    创建这样的结构后 type Foo struct name string func f Foo SetName name string f name name func f Foo GetName string return f name
  • python基类如何判断子类是否重写了它的方法?

    这是我的猜测 但行不通 class BaseClass object def foo self return foo def bar self return bar def methods implemented self This doe
  • Java:优化哈希集以进行大规模重复检测

    我正在开发一个项目 需要处理大量推文 目标是在处理重复项时删除它们 我有推文 ID 它们以以下格式的字符串形式出现 166471306949304320 我一直在使用HashSet