免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
123
最近访问板块 发新帖
楼主: gongyonghui2
打印 上一主题 下一主题

大数据去重复,求速度 [复制链接]

论坛徽章:
89
水瓶座
日期:2014-04-01 08:53:31天蝎座
日期:2014-04-01 08:53:53天秤座
日期:2014-04-01 08:54:02射手座
日期:2014-04-01 08:54:15子鼠
日期:2014-04-01 08:55:35辰龙
日期:2014-04-01 08:56:36未羊
日期:2014-04-01 08:56:27戌狗
日期:2014-04-01 08:56:13亥猪
日期:2014-04-01 08:56:02亥猪
日期:2014-04-08 08:38:58程序设计版块每日发帖之星
日期:2016-01-05 06:20:00程序设计版块每日发帖之星
日期:2016-01-07 06:20:00
21 [报告]
发表于 2014-05-23 23:51 |只看该作者
这个问题有很多种解决方法,我感觉最好利用数据自身的特点,lz贴出来的数据似乎有些规律性可以利用。

论坛徽章:
11
技术图书徽章
日期:2014-03-01 14:44:34天蝎座
日期:2014-05-21 22:11:59金牛座
日期:2014-05-30 17:06:14
22 [报告]
发表于 2014-05-24 11:51 |只看该作者
本帖最后由 timespace 于 2014-05-24 11:52 编辑

回复 20# MMMIX
是不太科学,从现在的结果也不足以倒推出原因。。。

从Perl官网找到一封1998年的C数据结构文档http://blob.perl.org/tpc/1998/Pe ... Perl%20Illustrated/,如今HASH函数可能不同,但基础数据结构应该还有参考价值,其中hash的实现:


考虑64位系统,load factor(元素个数/buckets)小于1,还没算上hash key字符串内容:
  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;

  4. # SvNULL (ANY, REFCNT, FLAGS & Type)
  5. my $SvNULL_size = 8*3;

  6. # SvPV (SvNULL, PVX, CUR, LEN)
  7. my $SvPV_size = $SvNULL_size + 8*3;

  8. # SvIV (SvNULL, IVX/NVX)
  9. my $SvIV_size = $SvNULL_size + 8;

  10. # HE (next, hek, val)
  11. my $bucket_size = 8;
  12. my $entry_size = 8*3 + 8*2 + $SvIV_size + $bucket_size;

  13. # HV
  14. my $entrys = 150e6;
  15. my $HV_size_min = $entrys * $entry_size;

  16. printf "hash size %.2f GB\n", $HV_size_min/2**30;
复制代码
输出:
  1. $ ./hash_storage.pl
  2. hash size 11.18 GB
复制代码
在加上原始字符串的2.5GB,那就是13.68GB,基本就是最保守的内存估计了,不过距离真实的19GB+还有不少空白。


   

论坛徽章:
95
程序设计版块每日发帖之星
日期:2015-09-05 06:20:00程序设计版块每日发帖之星
日期:2015-09-17 06:20:00程序设计版块每日发帖之星
日期:2015-09-18 06:20:002015亚冠之阿尔艾因
日期:2015-09-18 10:35:08月度论坛发贴之星
日期:2015-09-30 22:25:002015亚冠之阿尔沙巴布
日期:2015-10-03 08:57:39程序设计版块每日发帖之星
日期:2015-10-05 06:20:00每日论坛发贴之星
日期:2015-10-05 06:20:002015年亚冠纪念徽章
日期:2015-10-06 10:06:482015亚冠之塔什干棉农
日期:2015-10-19 19:43:35程序设计版块每日发帖之星
日期:2015-10-21 06:20:00每日论坛发贴之星
日期:2015-09-14 06:20:00
23 [报告]
发表于 2014-05-24 13:01 |只看该作者
本帖最后由 MMMIX 于 2014-05-24 13:02 编辑

回复 22# timespace


    我拿楼主提供的数据实际测试了一下,16M的数据(无重复),在运行时最多要占用 86M 多的空间,差不多是实际数据的五倍多。这 hash 快是快,可是占用空间也太多了点。

论坛徽章:
8
技术图书徽章
日期:2013-08-22 11:21:28未羊
日期:2015-01-19 22:22:25巳蛇
日期:2014-08-11 16:53:08子鼠
日期:2014-05-29 09:04:44摩羯座
日期:2014-04-11 14:15:07丑牛
日期:2014-01-24 12:41:28金牛座
日期:2013-11-21 17:38:28射手座
日期:2015-01-21 08:50:32
24 [报告]
发表于 2014-05-27 16:39 |只看该作者
本帖最后由 huang6894 于 2014-05-27 16:52 编辑

菜鸟来一个~
因为数据太大没下。。自己弄了100W行试了下~


论坛徽章:
42
19周年集字徽章-周
日期:2019-10-14 14:35:31平安夜徽章
日期:2015-12-26 00:06:30数据库技术版块每日发帖之星
日期:2015-12-01 06:20:002015亚冠之首尔
日期:2015-11-04 22:25:43IT运维版块每日发帖之星
日期:2015-08-17 06:20:00寅虎
日期:2014-06-04 16:25:27狮子座
日期:2014-05-12 11:00:00辰龙
日期:2013-12-20 17:07:19射手座
日期:2013-10-24 21:01:23CU十二周年纪念徽章
日期:2013-10-24 15:41:34IT运维版块每日发帖之星
日期:2016-01-27 06:20:0015-16赛季CBA联赛之新疆
日期:2016-06-07 14:10:01
25 [报告]
发表于 2014-05-27 20:26 |只看该作者
本帖最后由 laputa73 于 2014-05-27 21:30 编辑

回复 23# MMMIX


    以前测过redis的内存占用,大约是原始数据的4倍
   
   LZ给出的数据,第一二列重复率极高,应该有优化算法,类似用3层hash替代1层hash的方法(相当于减少了key的总数)。
  1. open IN,"tt1.txt";
  2. open OU,">","result.txt";
  3. my %hash=();
  4. my $line=0;
  5. while(<IN>){
  6.         chomp;
  7.         my @tmp=sort {$a<=>$b} split /\t/;        
  8.         $hash{$tmp[0]}{$tmp[1]}{$tmp[2]}++;
  9.         #print @tmp;
  10.         $line++;
  11.         last if $line >10000000;
  12. }
  13. print "sortDone\n";

  14. while(my ($cc)=each %hash){
  15.         print OUT $cc,"\n";        
  16. }
复制代码
测试了一下,处理前10M行,使用内存440M,1分多钟。
6G内存应该够用。

论坛徽章:
46
15-16赛季CBA联赛之四川
日期:2018-03-27 11:59:132015年亚洲杯之沙特阿拉伯
日期:2015-04-11 17:31:45天蝎座
日期:2015-03-25 16:56:49双鱼座
日期:2015-03-25 16:56:30摩羯座
日期:2015-03-25 16:56:09巳蛇
日期:2015-03-25 16:55:30卯兔
日期:2015-03-25 16:54:29子鼠
日期:2015-03-25 16:53:59申猴
日期:2015-03-25 16:53:29寅虎
日期:2015-03-25 16:52:29羊年新春福章
日期:2015-03-25 16:51:212015亚冠之布里斯班狮吼
日期:2015-07-13 10:44:56
26 [报告]
发表于 2014-05-27 20:33 |只看该作者

论坛徽章:
11
技术图书徽章
日期:2014-03-01 14:44:34天蝎座
日期:2014-05-21 22:11:59金牛座
日期:2014-05-30 17:06:14
27 [报告]
发表于 2014-05-27 20:56 |只看该作者
回复 26# zhlong8
太强大了,3ks。扫了一眼,内存确实变得更多了。


   

论坛徽章:
0
28 [报告]
发表于 2014-06-30 14:54 |只看该作者
本帖最后由 luwp 于 2014-06-30 14:55 编辑

我以前在linux/unix上是用sort  按指定列排序,然后去重

sort命令本身就是归并排序,你可以看到在tmp疯狂的生产大量的碎片,然后慢慢得到最终结果


sort命令不会把内存弄爆的
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP