免费注册 查看新帖 |

Chinaunix

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

Hash优化i [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-10-19 16:45 |只看该作者 |倒序浏览
20可用积分
不好意思,学perl的时间不多


所有代码:

#! /usr/bin/perl -w

use PerlIO::gzip;
#use strict;
#use diagnostics;

my $datcounttime=`/bin/sh datcounttime.sh`;
chomp($datcounttime);
my %TmpHash;

my $POPDir="/home/temp/pop1,/home/temp/pop2,/home/temp/pop3,/home/temp/pop4";
my @logDirNames = split /,/, $POPDir;

my $abc="abc=101,abc=103,abc=105,abc=107";
my @abcNames=split /,/, $abc;

my $counttime="counttime=0,counttime=1,counttime>1";
my @counttimeNames= split /,/, $counttime;

my $hourly="00,01,02,03,04,05,06,07,08,09,10,11,12,13,14,15,16,17,18,19,20,21,22,23";
my @hourlyNames = split /,/, $hourly;

#//以上面三个数组元素的组合字符串作为创建hash 的key, 初始值为0
foreach my $hourType (@hourlyNames) {
        foreach my $counttimeType (@counttimeNames) {
                foreach my $abcType (@abcNames) {
                        if($counttimeType eq "counttime>1"{
                                $counttimeType = "counttime=(?![01])";
                                $TmpHash{"$datcounttimehourType.*$abcType.*$counttimeType"} = 0;
                        }
                        else {
                                $TmpHash{"$datcounttimehourType.*$abcType.*$counttimeType"} = 0;
                        }
                }
        }
}

foreach my $logDirName (@logDirNames) {
        if ( ! -d $logDirName ){
                next;
        }
        print "$logDirName\n";

        my @logFileNames = <$logDirName/access*>;
        foreach my $logFileName (@logFileNames) {
                open (logFile, "<:gzip",  "$logFileName" or die "Can't open $logFileName: $!";
                while(<logFile> {
                                               如果当前行与hash中的某一个key(字符串)相匹配,则这个key对应的value加1
                }
                close logFile;
        }

}

while (my ($key, $value) = each (%TmpHash)) {         
      print "$key => $value\n";
}

如果去掉中间的foreach就是下面这样的输出:
[17\/Oct\/2009:16.*abc=105.*counttime=1.* => 0
[17\/Oct\/2009:02.*abc=103.*counttime=(?![01]).* => 0
[17\/Oct\/2009:08.*abc=107.*counttime=1.* => 0
[17\/Oct\/2009:04.*abc=105.*counttime=1.* => 0
[17\/Oct\/2009:12.*abc=107.*counttime=0.* => 0
[17\/Oct\/2009:01.*abc=103.*counttime=(?![01]).* => 0
[17\/Oct\/2009:07.*abc=105.*counttime=(?![01]).* => 0
[17\/Oct\/2009:11.*abc=107.*counttime=0.* => 0
[17\/Oct\/2009:17.*abc=103.*counttime=(?![01]).* => 0
[17\/Oct\/2009:14.*abc=105.*counttime=0.* => 0
[17\/Oct\/2009:14.*abc=103.*counttime=1.* => 0
[17\/Oct\/2009:15.*abc=103.*counttime=(?![01]).* => 0
[17\/Oct\/2009:00.*abc=101.*counttime=(?![01]).* => 0

[ 本帖最后由 HAHAPrince 于 2009-10-20 11:47 编辑 ]

最佳答案

查看完整内容

#! /usr/bin/perl -wuse PerlIO::gzip;#use strict;#use diagnostics;my $datcounttime=`/bin/sh datcounttime.sh`;chomp($datcounttime);my %TmpHash;my $POPDir="/home/temp/pop1,/home/temp/pop2,/home/temp/pop3,/home/temp/pop4";my @logDirNames = split /,/, $POPDir;my $abc="abc=101,abc=103,abc=105,abc=107";my @abcNames=split /,/, $abc;my $counttime="counttime=0,counttime=1,counttime>1";my @counttimeNames= sp ...

论坛徽章:
1
狮子座
日期:2013-12-16 16:09:24
2 [报告]
发表于 2009-10-19 16:45 |只看该作者
#! /usr/bin/perl -w

use PerlIO::gzip;
#use strict;
#use diagnostics;

my $datcounttime=`/bin/sh datcounttime.sh`;
chomp($datcounttime);
my %TmpHash;

my $POPDir="/home/temp/pop1,/home/temp/pop2,/home/temp/pop3,/home/temp/pop4";
my @logDirNames = split /,/, $POPDir;

my $abc="abc=101,abc=103,abc=105,abc=107";
my @abcNames=split /,/, $abc;

my $counttime="counttime=0,counttime=1,counttime>1";
my @counttimeNames= split /,/, $counttime;

my $hourly="00,01,02,03,04,05,06,07,08,09,10,11,12,13,14,15,16,17,18,19,20,21,22,23";
my @hourlyNames = split /,/, $hourly;



my @realkeys;


#//以上面三个数组元素的组合字符串作为创建hash 的key, 初始值为0
foreach my $hourType (@hourlyNames) {
        foreach my $counttimeType (@counttimeNames) {
                foreach my $abcType (@abcNames) {
                        if($counttimeType eq "counttime>1"{
                                $counttimeType = "counttime=(?![01])";
                                push @realkeys,"$datcounttimehourType.*$abcType.*$counttimeType";
                        }
                        else {
                                push @realkeys,"$datcounttimehourType.*$abcType.*$counttimeType";
                        }
                }
        }
}

foreach my $logDirName (@logDirNames) {
        if ( ! -d $logDirName ){
                next;
        }
        print "$logDirName\n";

        my @logFileNames = <$logDirName/access*>;
        foreach my $logFileName (@logFileNames) {
                open (logFile, "<:gzip",  "$logFileName" or die "Can't open $logFileName: $!";
                while(<logFile> {
                       if (/($datcounttimehourType.*$abcType.*$counttimeType)/)             #包含所有key类型的正则表达式
                       {
                            $TmpHash{($1)}++;
                       }
                }
                close logFile;
        }

}

foreach (@realkeys){
      print "$_ => $TmpHash{$_}\n";
}

论坛徽章:
1
狮子座
日期:2013-12-16 16:09:24
3 [报告]
发表于 2009-10-19 17:36 |只看该作者
多进程 or 多线程
以多线程为例,为几个不同的文件处理过程创建线程,将内容保存在多个子哈希里
主线程等待子线程完毕后,合并子哈希表
.
.
.
抛砖引玉一下

论坛徽章:
0
4 [报告]
发表于 2009-10-19 17:47 |只看该作者
  1.                 while (<logFile>) {
  2.                         while (my ($keytmp, $valuetmp) = each (%Hash)) {  
复制代码


两个循环呀大哥。
第二个while是不必要D。

while(<logFile>) {
    $hash{$key} += $value if $key =~ /.../;
}

论坛徽章:
0
5 [报告]
发表于 2009-10-19 17:57 |只看该作者
原帖由 兰花仙子 于 2009-10-19 17:47 发表
                while () {
                        while (my ($keytmp, $valuetmp) = each (%Hash)) {  

两个循环呀大哥。
第二个while是不必要D。

while() {
    $hash{$key} += $value if $key  ...



while(<logFile>) {
    $hash{$key} += $value if $key =~ /.../;
}
这个怎么写呢?

论坛徽章:
0
6 [报告]
发表于 2009-10-19 18:29 |只看该作者

  1. foreach my $key(keys %hash){#在循环外根据hash值长度重新建一个newhash
  2.     my $leng=length($key);
  3.     $new_hash{$leng}++;
  4. }
  5. while(<logFile>){
  6.     my @t=split '\[',$_;#分开到数组
  7.     foreach my $val(@t){#数据
  8.         foreach my $key(keys %new_hash){#按取hash值的长度
  9.             my $word=substr $val,0,$key;#将数据按长度处理
  10.             if(defined($hash{$word})){#判断hash里有没有defined
  11.                 $hash{$word}++;
  12.                 last;
  13.             }
  14.         }
  15.     }
  16. }
复制代码

我来写一个,主要是考虑把数据按长度截掉然后在hash里判断是否存在,有可能会快一点么,呵呵

论坛徽章:
0
7 [报告]
发表于 2009-10-19 19:42 |只看该作者

回复 #4 HAHAPrince 的帖子


  1.                 while (<logFile>) {
  2.                     if (/(some_match_key)/) {
  3.                         $Hash{$1} ++;
  4.                 }
复制代码


hash里的key不必判断其是否有初始value,直接递增就OK。

论坛徽章:
0
8 [报告]
发表于 2009-10-19 20:03 |只看该作者

回复 #6 兰花仙子 的帖子

lz的意思应该不是一行里只出现一个值的意思吧 可能有多个  
或者是我理解错了

论坛徽章:
0
9 [报告]
发表于 2009-10-20 09:04 |只看该作者
原帖由 兰花仙子 于 2009-10-19 19:42 发表

                while () {
                    if (/(some_match_key)/) {
                        $Hash{$1} ++;
                }


hash里的key不必判断其是否有初始value,直接递增就OK。


some_match_key 就是hash里的key...
就是说,我已经有了一个hash, hash 的每一个key都是一个正则表达式的字符串
例如:
$key1 = "kk.*few.*abc";
$hash{$key1}  = 0;

[ 本帖最后由 HAHAPrince 于 2009-10-20 10:03 编辑 ]

论坛徽章:
0
10 [报告]
发表于 2009-10-20 09:05 |只看该作者
原帖由 guap514 于 2009-10-19 20:03 发表
lz的意思应该不是一行里只出现一个值的意思吧 可能有多个  
或者是我理解错了



是的
一行里只出现一个值.
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP