免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2026 | 回复: 6
打印 上一主题 下一主题

数亿行数据随机抽取的效率问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2012-02-13 19:58 |只看该作者 |倒序浏览
本帖最后由 xxhacker 于 2012-02-13 19:59 编辑

我有一个用户列表,一个uid为一行,总共有数亿行之多,自己参考网上写了一个代码如下,如果行数小于几百万行的话,程序执行起来没有什么问题,但是一旦到了上亿行,这程序就特别的吃系统资源,主要是把读入的内容全部放到数组里去了,大家有没有什么更好的办法了?
  1. #! /usr/bin/perl -w
  2. use strict;
  3. use Getopt::Long;

  4. my $number;
  5. my %hash;

  6. GetOptions("number=n" => \$number);
  7. die usage() unless $number;

  8. my @array = <>;

  9. while ((keys %hash < $number)){
  10.     $hash{int(rand($#array))} = 1;
  11. }
  12. open FH,"> $number.txt" or die "Can't Write File:$!\n";
  13. print FH $array[$_] for keys %hash;
  14. close FH;


  15. sub usage {
  16.     my $PROG = $0;
  17.     print <<EOF;
  18. USAGE
  19.     cat xxx|$PROG OPTIONS
  20. OPTIONS:
  21.     --number|n  number lines
  22. EOF
  23. }
复制代码

论坛徽章:
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
2 [报告]
发表于 2012-02-13 20:40 |只看该作者
每读一行都 rand 下看要还是不要(比如100万个抽100个,那就是 rand() < 100/100万就取),直到抽满为止,如果读完了还不够就拿最后几个顶替。

论坛徽章:
0
3 [报告]
发表于 2012-02-13 21:05 |只看该作者
回复 2# zhlong8
版主说的也是一个思路,关键一点是我不知道这个文件有多少行数据,就意味着rand()<$NUM这个值不定,当然可以先用cat xxx|wc -l来取得行数,不过这样搞就太麻烦了


   

论坛徽章:
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
4 [报告]
发表于 2012-02-13 21:37 |只看该作者
xxhacker 发表于 2012-02-13 21:05
回复 2# zhlong8
版主说的也是一个思路,关键一点是我不知道这个文件有多少行数据,就意味着rand()


按文件大小估算下总没问题吧,你的数据不是很规律吗

论坛徽章:
6
15-16赛季CBA联赛之新疆
日期:2016-03-22 22:34:5915-16赛季CBA联赛之山东
日期:2016-04-11 09:08:41程序设计版块每日发帖之星
日期:2016-06-28 06:20:00程序设计版块每日发帖之星
日期:2016-07-19 06:20:00每日论坛发贴之星
日期:2016-07-19 06:20:0015-16赛季CBA联赛之青岛
日期:2016-07-20 22:44:17
5 [报告]
发表于 2012-02-13 22:22 |只看该作者
If you data is too big to fit in memory you can search for QDBM or Tokyo cabinet such that you can save the data in a hash on disk and then tie it in memory.

论坛徽章:
0
6 [报告]
发表于 2012-02-14 04:15 |只看该作者
本帖最后由 twilightagain 于 2012-02-14 04:19 编辑

使用标准模块Tie::File。

这个模块不会把数据一次读入内存,就是为了楼主这类问题设计的


Tie::File represents a regular text file as a Perl array. Each element in the array corresponds to a record in the file. The first line of the file is element 0 of the array; the second line is element 1, and so on.
The file is not loaded into memory, so this will work even for gigantic files.

以上摘自文档的description部分

论坛徽章:
0
7 [报告]
发表于 2012-02-14 12:54 |只看该作者
谢谢6楼推荐的模块,我刚才用这个模块跑了一下,确实不怎么占资源,不过跑起来就比较慢了
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP