2012-05-03 2 views
4

고정 길이 레코드 파일을 구문 분석하는 Perl로 작성된 구문 분석기가 있습니다. 레코드의 일부는 숫자로만 구성된 여러 문자열 (고정 길이도 포함)로 구성됩니다. 문자열의 각 문자는 ASCII char이 아닌 숫자로 인코딩됩니다. 즉, 문자열 12345가있는 경우 01 02 03 04 05 (31 32 33 34 35 대신)로 인코딩됩니다.Perl에서 조인과 결합 된 압축 해제 성능

언팩으로 레코드를 구문 분석하고이 특정 파트는 @array = unpack "C44", $s으로 압축을 풉니 다. 그런 다음 $m = join("", @array)처럼 간단한 조인으로 필요한 문자열을 복구합니다.

디코딩 할 최적의 방법인지 궁금합니다. 파일은 상당히 크고 수백만 개의 레코드가 있습니다. 분명히 최적화가 가능한지 살펴 보았습니다. 프로필러는 대부분의 시간이 레코드 구문 분석에 소비된다는 것을 보여줍니다 (예 : 읽기, 쓰기 및 기타 문제는 문제가되지 않음). 대부분의 시간을 구문 분석하는 데 이러한 조인이 사용되었습니다. 다른 소스에서 조인은 매우 효율적인 작업임을 기억합니다. 코드의 속도를 높이는 것이 가능한지 또는 이미 최적인지 여부에 대한 아이디어가 있습니까? 예를 들어 pack/unpack 조합을 사용하는 등 영리한 방법으로이 중간 배열을 피하는 것이 가능할까요?

편집 : 코드 예제

이 같은 모습을 최적화하기 위해 노력 코드 : 언제나처럼 펄

while (read(READ, $buf, $rec_l) == $rec_l) { 
     my @s = unpack "A24 C44 H8", $buf; 
     my $msisdn = substr $s[0], 0, 11; 
     my $address = join("", @s[4..14]); 
     my $imsi = join("", @s[25..39]); 
     my $ts = localtime(hex($s[45])); 
    } 

답변

0

, 빨리가 덜 읽을 수 :-)

join("", unpack("C44", $s)) 

이 변경으로 인해 코드 속도가 빨라질 것이라고 생각하지 않습니다. 모든 것은 join 함수를 호출하여 하나의 전체 파일을 읽는 빈도에 달려 있습니다. 청크로 작업하는 경우에는 크기를 늘려보십시오. 압축을 풀고이 배열에 조인하는 동안 일부 작업을 수행하는 경우 맵 작업을 통해 배열을 시도하십시오. 소스 코드를 게시하면 병목 현상을 쉽게 식별 할 수 있습니다.

+0

질문에 더 많은 코드가 추가되었습니다. – MariusM

0

나는 팩/압축 풀기 멍청한 놈이야,하지만 지금처럼 샘플 코드를 변경하여 가입 건너 뛰는에 대한 방법 :

my $m = unpack "H*", $s ; 

빠른 테스트 :

#!/usr/bin/perl 

use strict ; 
use Test::More tests => 1 ; 

is(unpack("H*", "\x12\x34\x56"),"123456"); 
6

테스트되지 않은 (내가 갈 게요 다시 바쁘지 않을 때 편집) 그러나 모든 수학을 올바로 수행하면 더 빨리 수행해야합니다.

my ($msisdn, $address, $imsi, $ts) = 
    unpack "A11 x13 x3 a10 x10 a15 x5 N", $buf; 
$address |= "0" x 10; 
$imsi |= "0" x 15 
$ts = localtime($ts); 
+0

작은 수정 만이 필요하고, 이것 외에는 올바로 작동합니다. 그리고 내 것보다 두 배 빠릅니다. 이 압축을 들여다 보니 나는이 조인을 어떻게 처리 할 수 ​​있었는지 궁금하다. ( – MariusM

+0

@MariusM 정정이 무엇인지 말해 주면 내 대답을 편집 해 드리겠습니다. – hobbs

+1

'hex unpack 'H8'is a – ikegami