免费注册 查看新帖 |

Chinaunix

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

关于大规模数组的搜索问题(续) [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2014-01-15 15:05 |只看该作者 |倒序浏览

以前的问题是“问题是这样的,我有一个很大的字符串数据集,按一定规则可以切成块,然后push入数组,大约有40,000,000个元素,现在需要拿一个目的字符串对这个数组进行遍历搜索,利用my $srID=index($array[0],$keyword);判断每个数组元素中是否还有该目的字符串,可是全部4千万个元素遍历完需要时间大约5min左右,时间比较久。。。

如果不用array,用hash的话会不会快一些呢?或者有其他的更快的算法没”
大家的回复我看了一下,可能是我的问题没有描述清楚,下面贴上一小段程序,我的想法是能不能利用多线程,比如单线程的时候4千万个数组元素需要一个一个遍历,如果开4个线程,把数组分成4各部分,每个部分在单独的线程中跑,然后搜索到有关键词的数组元素输出到一个新的数组里,不晓得可行不?我试了一下,按说应该更快才对,但是这样多线程反而比单线程更慢,不晓得什么原因,我是VB转到perl的新手,程序写的不是很好,请各位大神看看是我的思路有问题,还是程序写的问题?或者是线程共享数据没设置好,造成信号阻塞?

#!/usr/bin/perl  
use strict;   
use threads;
use threads::shared; #share data
use Thread::Semaphore;
my @dbcut:shared=(); #切割后的数据集,有40,000,000个元素
my @keywordseqtem:shared;
my $count:shared=0;
my $max_threads;#多线程数目
my $semaphore=new Thread::Semaphore($max_threads);
my $keyword='bateria';#搜索关键词
##multi-threads processing######################################
#想法是利用多线程,将大数组@dbcut按照启动的线程数切割为几部分,分别在线程中#跑。
   my $numthrds=0;#创建的进程数
   my $startid =0;
   my $endid=-1;
   my $numseqsstep=int(($#dbcut+1)/$max_threads);
    while(){   
      if($endid>$#dbcut){   
         last;
      }
          $startid =$endid+1;
          $endid=$startid+$numseqsstep-1;
           $semaphore->down();         
           my $thread=threads->new(\&cir,$keyword,$startid,$endid);
           $thread->detach();   
           $numthrds=$numthrds+1;         
     }
################################################
sub cir{
my ($keyword,$startid,$endid)=@_;
for (my $j=$startid;$j<=$endid;$j++){
    my $srID=index($dbcut[$j],$keyword);
    if ($srID==-1){
     print 'No Hitting!'."\n";
    }
    else{
     lock ($count);
     $keywordseqtem[$count]=$dbcut[$j];
     $count++;
   }
}
$semaphore->up();
}

论坛徽章:
23
15-16赛季CBA联赛之吉林
日期:2017-12-21 16:39:27白羊座
日期:2014-10-27 11:14:37申猴
日期:2014-10-23 08:36:23金牛座
日期:2014-09-30 08:26:49午马
日期:2014-09-29 09:40:16射手座
日期:2014-11-25 08:56:112015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:49:0315-16赛季CBA联赛之山东
日期:2017-12-21 16:39:1915-16赛季CBA联赛之广东
日期:2016-01-19 13:33:372015亚冠之山东鲁能
日期:2015-10-13 09:39:062015亚冠之西悉尼流浪者
日期:2015-09-21 08:27:57
2 [报告]
发表于 2014-01-15 15:18 |只看该作者
说原始需求,不要说你啃了一半的。
很多时候你一开始的方向就是有问题的。

论坛徽章:
0
3 [报告]
发表于 2014-01-15 15:55 |只看该作者
本帖最后由 csubiohulqi 于 2014-01-15 15:59 编辑

回复 2# ly5066113

原始需求就是,有一个很大的数组@dbcut,有4千万个元素(都是字符串),共29G左右,我有一个关键字$keyword,要在这四千万个元素中找出哪些元素含有这个关键字,并输出到新的数组中。。。

我用的是数组遍历查找,my $srID=index($array[$i],$keyword);判断每个数组元素中是否还有该目的字符串,可是全部4千万个元素遍历查找完需要时间大约5min左右,时间比较久。。。怎么样可以更快一些

论坛徽章:
23
15-16赛季CBA联赛之吉林
日期:2017-12-21 16:39:27白羊座
日期:2014-10-27 11:14:37申猴
日期:2014-10-23 08:36:23金牛座
日期:2014-09-30 08:26:49午马
日期:2014-09-29 09:40:16射手座
日期:2014-11-25 08:56:112015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:49:0315-16赛季CBA联赛之山东
日期:2017-12-21 16:39:1915-16赛季CBA联赛之广东
日期:2016-01-19 13:33:372015亚冠之山东鲁能
日期:2015-10-13 09:39:062015亚冠之西悉尼流浪者
日期:2015-09-21 08:27:57
4 [报告]
发表于 2014-01-15 16:09 |只看该作者
回复 3# csubiohulqi


“我有一个很大的字符串数据集,按一定规则可以切成块,然后push入数组”

数据集从何而来?
按什么规则切块?
按关键字查找的目的是什么?

你的数组@dbcut,关键字$keyword查找,只是为了实现某种需求的方法,而不是原始的需求。

论坛徽章:
0
5 [报告]
发表于 2014-01-15 16:44 |只看该作者
回复 4# ly5066113




具体的原始需求就是:
有一个原始大文件,是fasta格式的序列文件,以‘>’为标识符。

原始文件内部格式如下:
>序列名称1
ATCG......GTCA
>序列名称2
ATCG......GTCA
>序列名称3
ATCG......GTCA
等等
共有4千余万条序列。

我要做的就是对关键字符串进行搜索,找出序列名称中有我寻找的关键词的序列,并输出出来。。。


不晓得这次表达的清晰不?呵呵,我的想法是以‘>’为标识符进行切割,推入数组,然后对数组每个元素进行搜索,如果含有关键字,则将该元素输出。。。但是速度有点慢,于是我又想到能不能开多线程处理,结果发现更慢。。。

还有个题外话,我想问一下,perl中对共享变量lock后还需要解锁吗?还是自动解?

论坛徽章:
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
6 [报告]
发表于 2014-01-15 16:46 |只看该作者
29G难道都在内存里面了?
如果在文件里面, 我觉得5分钟能做完已经很快了啊.

论坛徽章:
8
技术图书徽章
日期:2013-09-30 08:51:28技术图书徽章
日期:2013-12-11 09:26:39白羊座
日期:2013-12-27 15:27:13金牛座
日期:2014-01-06 09:13:05天蝎座
日期:2014-01-21 14:23:28酉鸡
日期:2014-05-09 16:51:12卯兔
日期:2014-08-11 16:49:1515-16赛季CBA联赛之八一
日期:2017-08-14 23:24:57
7 [报告]
发表于 2014-01-15 16:50 |只看该作者
本帖最后由 xiumu2280 于 2014-01-15 16:56 编辑

你的关键词是 my $keyword='bateria'
也就是你只要搜索>这一行就行了

你用index肯定慢
用正则啊··
my $srID=index($dbcut[$j],$keyword);
改成
$dbcut[$j] =~/\Q$keyword\E/;

你可以把大文件切成小文件再做

论坛徽章:
23
15-16赛季CBA联赛之吉林
日期:2017-12-21 16:39:27白羊座
日期:2014-10-27 11:14:37申猴
日期:2014-10-23 08:36:23金牛座
日期:2014-09-30 08:26:49午马
日期:2014-09-29 09:40:16射手座
日期:2014-11-25 08:56:112015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:49:0315-16赛季CBA联赛之山东
日期:2017-12-21 16:39:1915-16赛季CBA联赛之广东
日期:2016-01-19 13:33:372015亚冠之山东鲁能
日期:2015-10-13 09:39:062015亚冠之西悉尼流浪者
日期:2015-09-21 08:27:57
8 [报告]
发表于 2014-01-15 16:52 |只看该作者
回复 5# csubiohulqi


这个用 perl 读文件,正则表达式匹配一下,然后输出不就行了么?何必放数组里?

论坛徽章:
8
技术图书徽章
日期:2013-09-30 08:51:28技术图书徽章
日期:2013-12-11 09:26:39白羊座
日期:2013-12-27 15:27:13金牛座
日期:2014-01-06 09:13:05天蝎座
日期:2014-01-21 14:23:28酉鸡
日期:2014-05-09 16:51:12卯兔
日期:2014-08-11 16:49:1515-16赛季CBA联赛之八一
日期:2017-08-14 23:24:57
9 [报告]
发表于 2014-01-15 16:53 |只看该作者
他用的应该是服务器,一般电脑存29G的内容进数组··估计已经崩了··回复 6# laputa73


   

论坛徽章:
0
10 [报告]
发表于 2014-01-15 16:56 |只看该作者
回复 6# laputa73

都在内存里,小型服务器,内存96G
   
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP