java字符串表表容量_java – 我可以使用什么符号表来存储~50 mil的字符串,快速查找而不会耗尽堆空间?...
我有一个约5000万字符串的文件,我需要在启动时添加到某种符号表中,然后以合理的速度搜索几次.
我尝试使用DLB trie,因为查找会相对较快,因为所有字符串都是< 10个字符,但在填充DLB时,我会得到超出GC开销限制或outofmemory - 堆空间错误.使用HashMap发现了相同的错误.这是一个由分级器编译和运行的赋值,所以我宁愿不只是分配更多的堆空间.是否有不同的数据结构可以减少内存使用,同时仍然有合理的查找时间?
解决方法:
如果您期望低前缀共享,那么trie可能不是您的最佳选择.
由于您只在启动时加载查找表一次,并且您的目标是内存占用率低且查找速度“合理”,因此最佳选择可能是排序数组和二进制搜索查找.
首先,将数据加载到数组中.由于您可能不知道前面的大小,因此您将加载到ArrayList中.然后从列表中提取最终数组.
假设您加载了5000万个10个字符的字符串,内存将是:
10 character string:
String: 12 byte header + 4 byte 'hash' + 4 byte 'value' ref = 24 bytes (aligned)
char[]: 12 byte header + 4 byte 'length' + 10 * 2 byte 'char' = 40 bytes (aligned)
Total: 24 + 40 = 64 bytes
Array of 50 million 10 character strings:
String[]: 12 byte header + 4 byte 'length' + 50,000,000 * 4 byte 'String' ref = 200,000,016 bytes
Values: 50,000,000 * 64 bytes = 3,200,000,000 bytes
Total: 200,000,016 + 3,200,000,000 = 3,400,000,016 bytes = 3.2 GB
当您转换ArrayList< String>时,您将需要另一个String []副本. to String []. Arrays.sort()操作可能需要50%的数组大小(~100,000,000字节)用于临时存储,但如果在排序之前为GC发布了ArrayList,则可以重用该空间.
因此,总需求约为3.5 GB,仅适用于符号表.
现在,如果空间确实非常珍贵,你可以挤压它.如您所见,String本身在64字节中增加了24字节的开销.您可以使符号表直接使用char [].
此外,如果您的字符串都是US-ASCII或ISO-8859-1,则可以将char []转换为byte [],从而节省一半的字节.
组合在一起,将值大小从64字节减少到32字节,总符号表大小从3.2 GB减少到1.8 GB,或在加载期间大约2 GB.
UPDATE
假设输入的字符串列表已经排序,下面是如何执行此操作的示例.作为MCVE,它只使用一个小的静态数组作为输入,但您可以轻松地从文件中读取它们.
public class Test {
public static void main(String[] args) {
String[] wordsFromFile = { "appear", "attack", "cellar", "copper",
"erratic", "grotesque", "guitar", "guttural",
"kittens", "mean", "suit", "trick" };
List wordList = new ArrayList<>();
for (String word : wordsFromFile) // Simulating read from file
wordList.add(word.getBytes(StandardCharsets.US_ASCII));
byte[][] symbolTable = wordList.toArray(new byte[wordList.size()][]);
test(symbolTable, "abc");
test(symbolTable, "attack");
test(symbolTable, "car");
test(symbolTable, "kittens");
test(symbolTable, "xyz");
}
private static void test(byte[][] symbolTable, String word) {
int idx = Arrays.binarySearch(symbolTable,
word.getBytes(StandardCharsets.US_ASCII),
Test::compare);
if (idx < 0)
System.out.println("Not found: " + word);
else
System.out.println("Found : " + word);
}
private static int compare(byte[] w1, byte[] w2) {
for (int i = 0, cmp; i < w1.length && i < w2.length; i++)
if ((cmp = Byte.compare(w1[i], w2[i])) != 0)
return cmp;
return Integer.compare(w1.length, w2.length);
}
}
产量
Not found: abc
Found : attack
Not found: car
Found : kittens
Not found: xyz
标签:java,memory
来源: https://codeday.me/bug/20190608/1199027.html
java字符串表表容量_java – 我可以使用什么符号表来存储~50 mil的字符串,快速查找而不会耗尽堆空间?...相关推荐
- java arraylist指定容量_Java中的ArrayList的容量
List接口的大小可变数组的实现.实现了全部可选列表操做,并容许包括 null 在内的全部元素. ArrayList继承于List接口,除继承过来的方法外,还提供一些方法来操做内部用来存储列表的数组的 ...
- java 正则切分句子_Java开发笔记(三十七)利用正则串分割字符串
前面介绍了处理字符串的常用方法,还有一种分割字符串的场景也很常见,也就是按照某个规则将字符串切割为若干子串.分割规则通常是指定某个分隔符,根据字符串内部的分隔符将字符串进行分割,例如逗号.空格等等都可 ...
- java list初始容量_java中快速创建带初始值的List和Map实例
java中快速创建带初始值的List和Map实例 初始化一个List和Map对象并为期加入值的写法如下: List sList = new ArrayList(); sList.add("s ...
- java怎么设置序号_Java 添加Word项目符号、编号列表
import com.spire.doc.*; import com.spire.doc.documents.ListPatternType; import com.spire.doc.documen ...
- java 二维矩阵_Java如何输入二维矩阵并存储到二维数组中
展开全部 最不严谨的写法(但是可62616964757a686964616fe59b9ee7ad9431333335326163用)下列方法可以不需知道二维数组的宽度和长度,但是不能直接保存,而是输入 ...
- 基础-符号表(一)-数据结构和算法(Java)
文章目录 1 概述 2 API 2.1 泛型 2.2 重复的键 2.3 空(null)键 2.4 空(null)值 2.5 删除操作 2.6 便捷方法 2.7 迭代 2.8 键的等价性 3 有序符号表 ...
- plsql 无法解析指定的连接标识符_Java方法加载、解析、存储、调用
方法调用在项目中是数不胜数,除了一些常量类其他的类都会定义方法并调用,那你有想过他是怎么从一个java语言写的方法到计算机执行的吗,下面我们就来学习Class字节码文件中保存java中的方法.方法加载 ...
- java字符串拼接例子_Java详解【String】+【StringBuilder vs StringBuffer】+【字符串拼接】...
String详解 注意区分对象和对象的引用 首先来看一下我在jdk中找到的String源代码,这里只截取开头的小小一部分 public final class String implements ja ...
- java 字符串 面试题_Java常用类String的面试题汇总(java面试题)
1.比较两个字符串时使用"=="还是equals()方法? 当然是equals方法."=="测试的是两个对象的引用是否相同,而equals()比较的是两个字符串 ...
最新文章
- 如何定时备份数据库并上传七牛云
- 推荐几款vs2005的插件
- TRIZ系列-创新原理-23-反馈原理
- 还不起9亿?有人建议为范冰冰发行一款私募ABS产品融资!
- python 3.8.2_python-3.8.2-docs-html
- 新零售时代,美妆行业如何打造新主场?
- 许晴×××汤的营养价值
- C++函数模板(模板函数)详解
- 使用数位板或数位屏的压感笔时常见的问题及解决方法
- 软件测试---组织架构图和范围测试列表
- 163免费企业邮箱服务地址
- ProxySQL+MGR实现读写分离和主节点故障无感知切换 - 完整操作记录
- ThinkPHP实现定时执行任务的两种方法
- 【翻译论文】Understanding Reuse, Performance, and Hardware Cost of DNN......
- POS机刷卡跨行交易的清算方式
- iOS企业版app部署到自己的服务器
- JavaScript中的设计模式
- NAT与NAT穿透(一)
- 默认网络设备流量控制
- 四、V4L2 control结构框架图
热门文章
- Technical attribute VS Read only attribute
- SAP ABAP实用技巧介绍系列之 ABAP XSLT select keyword
- why my pricing procedure is not determined in QHD 504
- Java源码研究之object to json string debug
- add to -append Backend implementation
- 使用Cordova将您的前端JavaScript应用打包成手机原生应用
- One Order行项目里Item Category是怎么计算出来的
- ionic2 html 转义,ionic2 基于ngx-translate实现多语言切换,翻译
- high severity error mysql_pg将运行日志导入表中的方法及时区问题解决
- java 委托_面试官:java双亲委派机制及作用