作者johnhao1206 (Ya大熊)
看板java
标题[问题] 资料量很大的处理
时间Thu Mar 8 21:37:13 2012
现在正在写一个程式处理一个极大的文章 (256MB)
目前写的方法是硬把他存到二维阵列之中再去做处理
基本的格式是这样
id data1 data2 data3 ...
现在困扰的是要去找到对应id的资料去做处理的时候
搜寻整个array需要花费相当多的时间 (也要考虑记忆体的问题)
上网看了几个方法但是好像不是我要的
1.File Channel
不用读入整个档案可以减少记忆体花费
(但是external search不是很花时间吗?)
2.Map
有尝试用map的方法去做,但是这样耗费的记忆体好像会相当庞大
(我初始给到512MB了还是会爆炸)
3.
这个不知道是不是方法,
想把原本的资料按照id排序之後再用binary search
希望可以增加搜寻速度
不知道各位有没有什麽方法处理这种问题?
--
※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 114.42.188.43
1F:→ pico2k:改用x64的环境 03/08 21:47
2F:→ Lordaeron:NoSQL 来处理吧, 256GB 都好(我随便讲的) 03/08 21:51
3F:→ james732:丢进sqlite 03/08 22:12
4F:→ Chikei:存Map<Id, FilePos>,找Id之後直接跳到档案中FilePos存取 03/08 22:17
5F:→ johnhao1206:谢谢!! 我试试看Map(id,FilePos)的方法 03/08 22:21
6F:→ awert:RandomAccessFile ? 不知道适不适合 03/08 22:24
7F:→ qrtt1:重点不是资料量,而是你最後要得到什麽。有这个才能提策略. 03/08 22:46
我要的就很像是做一个查表法,要依照id去取得不同的数值
但是id不是照顺序排列,
而且查询的key分别有(id1)、(id1,id2)、(id1,id2,id3)三种组合
(所以不能用id当作array的index直接去access)
array里面的资料只要取得,不用更动 (增加、删除等等)
○ 刚刚用存Map<Id, FilePos>测试效率提升很多,谢谢
○ 我错了!! 因为我程式写错的关系,所以它只存到(id1)的组合
难怪跑这麽顺,处理三种组合还是会爆炸 继续尝试看看
8F:推 LaPass:id1 id2 id3分别是什麽? 03/09 13:09
9F:→ johnhao1206:都是数字 (0~72646) 但我把它存成String 03/09 13:41
Map1<String,int> Map2<String[],int> Map3<String[],int>
三种组合我分别做三个map处理这样
10F:→ johnhao1206:照理来说应该分别是会有72646,72646^2,72646^3笔资料 03/09 13:47
11F:推 LaPass:你的文章格是是像这样吗? 03/09 15:15
12F:→ LaPass: 2433 5215 6544 5644 03/09 15:16
13F:推 LaPass:後面的部分看不太懂到底想干什麽..... 03/09 15:19
不好意思 我举个例子
一整个档案分为三个区段
id1 data data
------------
0 0.1 0.2 我现在存的方法是把三个区段分别存在三个Map中
1 0.5 0.2
2 0.1 0.2 String section1 = id
3 0.4 0.2 Map1.put(section1,FilePos)
id1 id2 data data
---------------
0 0 0.3 0.2 String[] section2 = {id1,id2}
0 1 0.5 0.2
0 2 0.1 0.4 Map2.put(section2,FilePos)
0 3 0.1 0.2
1 0 0.3 0.6 Map2跟Map3都是存String[]当作key
id1 id2 id3 data data
------------------
0 0 0 0.1 0.1
0 0 1 0.1 0.1
0 0 2 0.1 0.1
0 0 3 0.1 0.1
14F:推 LaPass:用TreeMap<String,Integer>,然後Key为 0 0_0 0_0_0 03/09 16:34
15F:→ LaPass:Integer为行数,或是其他可以找到档案位置的东西。 03/09 16:36
16F:→ LaPass:FilePos我没用过,不清楚那个东西的特性,我还要再看。 03/09 16:37
17F:→ LaPass:不行.... 感觉起来还是会有问题.... = = 03/09 16:39
18F:→ LaPass:你还是用资料库吧 (晕死) 03/09 16:40
19F:→ johnhao1206:後来我把VM的记忆体改更大硬跑可以了 03/09 17:31
20F:→ johnhao1206:但我想还是学学资料库才是长久之计,谢谢大家 03/09 17:33
21F:→ Lordaeron:就NoSQL 了嘛, 快去学吧, 红哦 03/09 21:32
22F:推 LaPass:NoSQL也听一阵子了,那东西到底怎麽用.... = = 03/09 23:54
23F:→ johnhao1206:那个我也不是很清楚,是像hadoop之类的东西吗? 03/10 08:40
24F:推 SansWord:学资料库吧。用资料库轻松搞定的问题,不用自己造轮子 03/10 11:51
今天改成资料库的做法去写
但是速度实在是太悲剧了... 可能因为太频繁存取的关系
晚点改成X64的环境好了 ~"~
25F:→ qrtt1:你现在是写成什麽样子啊,真好奇QQ 03/11 00:19
我现在要做的举个简单的例子就像是食字路口的游戏,从头走到尾要花最少的钱
因为考虑的状况很多而且算钱的时候必须去参考那个大的档案表
而且价钱会因为上一个食物跟上上个食物而有所不同
所以才会遇到这样的困难
我现在的作法是先把档案表读入二维阵列之中
读取资料的时候顺便把它丢到Map之中建立
Key是食物的名子,Value是存在阵列之中的index
这样速度有快很多,只是记忆体真的吃很大
※ 编辑: johnhao1206 来自: 114.44.179.244 (03/11 08:16)
26F:→ qrtt1:你的 key 重复那麽多,可以用同一个物件会再省很多。 03/11 10:10
27F:→ Lordaeron:NoSQL 你要跟hadoop 划上等号也可以, 反正台式简化 03/11 21:13
28F:→ qrtt1:hadoop 其实是一大群专案的名称,用什麽功能要细看xd 03/11 21:57
29F:→ Lordaeron:说来说去hadoop 就是一个人家帮你写好的DHT. 03/11 22:34
30F:推 Chikei:72646^3笔资料冏,先想想演算法来减少资料量吧 03/12 11:37
31F:→ braveht:如果有72646^3笔资料,档案大小应该远远大於256MB。 03/12 21:55
32F:→ braveht:如果资料量是256MB,又强调速度的话,塞进记忆体是最佳解 03/12 21:58
33F:→ braveht:如要再省空间可参考qrtt1的建议,或用int来取代string 03/12 22:07
34F:→ johnhao1206:谢谢您的建议,现在也朝着这个想法努力中 也谢谢qrtt1 03/13 00:24
35F:推 chen1025:资料库建索引应该就可以解决了 03/13 23:50
资料库有测试过,但速度方面不太能够接受
※ 编辑: johnhao1206 来自: 114.44.179.244 (03/14 00:54)
36F:→ nick23:用SQLite 把资料放到ram disk 会好一点吗? 03/18 02:08