2015-01-20 2 views
0

현재 추출 로그가 필요한 스크립트가 있습니다. 다음은 Perl 코드 단편입니다. 스크립트는 모든 서버 폴더를 탐색하고 필요한 정보를 grep합니다. 문제는 로그 수가 너무 많아지면 스크립트를 완료하는 데 시간이 오래 걸릴 수 있습니다. 병목 목은 다음과 같습니다.이 Perl 스크립트의 grep 속도를 높이는 방법

이 작업 속도를 높이려면 어떤 방법이 있을까요? 스크립트는 CPU 및 8G 메모리 당 8 개의 코어가있는 서버에서 실행 중이므로 이러한 리소스를 사용할 수있는 방법이 있습니까?

my $grep = ($leaflog_zipped) ? "zgrep" : "grep" ; 
my %leaf_info; 
my @stage = ("STAGE1", "STAGE1", "STAGE3"); 
foreach my $leaf_dir (@leaf_dir_list){ 
    my $grep_path = $log_root_dir . "/$leaf_dir/*" ;   
    foreach my $current_stage (@stage){ 
     my @leaf_lines; 
     @leaf_lines = qx($grep -l "stagename = $current_stage" $grep_path| xargs $grep "Keywords"); ## how to improve the grep speed? 
     foreach (@leaf_lines){ 
      if(...){ 
       $leaf_info{$current_stage}{xxx} = xxxx; 
      } 
     }  
    } 
} 

답변

0

예. xargsGNU Parallel 또는 다른 유사한 프로그램으로 바꾸기 만하면됩니다 (일부 Linux 시스템에서는 parallel이라는 프로그램이 여러 개 있으므로 염두에 두어야하며 GNU 병렬이 가장 좋습니다).

1

우선 - '껍질을 벗기지 마십시오'라고 말하고 싶습니다 - perl은 패턴 매칭과 정규 표현식에 내장되어 있으며 정규 표현식을 사전 컴파일하는 기능을 포함하고 있습니다.

http://perldoc.perl.org/perlop.html#Regexp-Quote-Like-Operators

또한 - 당신은 당신의 CPU 리소스를보다 효율적으로 사용하게 스레딩 또는 포크를 사용하여 비교적 쉽게 병렬로 펄을 실행할 수 있습니다.

그러나 나는 grep과 같은 것들은 일반적으로 CPU 관련 문제가 아니라는 점을 지적 할 것입니다. 요즘은 파일 시스템이 일반적으로 훨씬 느린 CPU가 꽤 빠릅니다. 아마도 디스크에서 데이터를 읽는 데 드는 시간을 처리하는 것보다 더 많은 시간을 할애해야 할 것입니다.

그래서 당신에게 슬픔을 많이 줄 수있는 것은 여러 번 grep하는 것입니다.

my $grep_path = $log_root_dir . "/$leaf_dir/*" ;   
foreach my $current_stage (@stage) 

@stage의 각 요소는 다른 그렙을 유발하고, 그 디렉토리에있는 모든 파일에 대해 그렇게하고있어. 그리고 나서 을 다시 grepping합니다..

모든 파일을 여러 번 읽으므로 알고리즘이 좋지 않습니다. 더 이상 다음과 같이하지 마세요.

#could do this with map - I haven't for clarity. 
my %stages; 
$stages{'STAGE1'}++; 
$stages{'STAGE2'}++; 
$stages{'STAGE3'}++; 

foreach my $file (glob $grep_path) { 
    open(my $input_fh, "<", $file) or die $!; 
    while (<$input_fh>) { 
     if (m/current_stage/) { 
      my ($file_stage) = (
       m/stagename = (\w+)/; 
      ); 
      if ($stages{$file_stage}) { 
       # do something here 
      } 
     } 
    } 
} 

그런 식으로 모든 파일을 읽어야합니다. 한 번만 수행하면됩니다.

관련 문제