2013-07-25 5 views
0

내 이해 정확 :펄 Effeciency 내부 동안 다음과 같은 상태 때 테스트 ARGV는 (<>)는 루프

테스트 CPU 사이클을 낭비 $ ARGV 내부의 조건 (즉, 파일 이름) while (<>) 루프. 파일 이름을 먼저 테스트하고 while() 루프 내에서 각 행을 적절하게 처리하는 것이 더 효율적입니다. 이 방법은 데이터 라인을 잡을 때마다 파일 이름을 중복 검사하지 않습니다.

아니면 다이아몬드 운영자가 후자만큼 효율적으로 이것을 만들 수 있습니까?

+0

'$ ARGV '를 테스트하는 것보다'eof'를 사용하는 것이 더 좋습니다. 'perldoc -f eof'를보십시오 : http://perldoc.perl.org/functions/eof.html – shawnhcorey

답변

2

CPU주기를 낭비하고 있습니까?

Perl입니다. VM에서 실행됩니다. 포인터가 역 참조 전역 변수의 간단한 조회가 함축하는 의미가 있습니까? 왜 주기를 걱정 하시겠습니까??/s

<> 연산자는 상당한 양의 마법을 암시하지만 루프를 최적화하지는 않습니다. 따라서,

my $lastfile = ""; 
while (<>) { 
    say "file changed to ", $lastfile = $ARGV if $lastfile ne $ARGV; 
    print "> $_"; 
} 

ne 체크는 모든 단일 라인에 대해 실행됩니다. 코드 크기 또는 개발 시간을 최적화하는 경우 이는 전적으로 허용됩니다. 나는 개인적으로 (단일 지정 양식) 더 우아한 수 있도록이 양식을 찾을 수

use autodie; 
for my $file (@ARGV) { 
    open my $fh, "<", $file; 
    say "file changed to $file"; 
    while (<$fh>) { 
    print "> $_"; 
    } 
} 

, 그것은 : 당신이 실행 오피 코드의 총 수를 최적화하는 경우, 때로는 명시 적으로 파일의 개방을 싸게 할 수있다 어쨌든 그렇게 오래 걸리지 않습니다. 그러나 신속한 oneliner에서, 나는 더 긴 형식을 작성하는 동안 스크립트가 이미 1000 번 실행되었을 수 있으므로 첫 번째 솔루션을 사용합니다.

0

개념 증명 (아래 참조)으로 저는 그림 10에있는 두 개의 스크립트 (각각 poc.pl 및 poc2.pl로 이름을 붙였습니다)를 10 억 개의 파일로 실행했습니다. 전자는 21.7 % 느려졌다. 결론적으로 이것은 엄청난 양의 행을 처리 할 때만 중요합니다. 이 경우 더 낮은 수준의 언어가 더 나은 선택 일 수 있습니다.

bash $ wc -l large.log 
1000000000 large.log 
bash $ time perl poc.pl large.log >/dev/null 
    291.16s real 289.89s user  0.73s system 
bash $ time perl poc2.pl large.log >/dev/null 
    239.29s real 238.58s user  0.53s system