2017-01-11 4 views
0

다음은 속도를 향상시키기 위해 노력한 코드 조각입니다.decode_utf8은 실행 시간을 소모합니다.

use strict; 
use warnings; 
use Encode; 

open(IN,"<utf8",$ARGV[0]) or die "Cannot open $ARGV[0]:$!\n"; ##treat it as a huge data of 35,000 lines in devnagari script. 
my @in = <IN>; 
close(IN); 

my $key = "अच्छा"; #key to be matched contains devanagari script as a string 

foreach my $in(@in) { 
    chomp($in); 
    $key = decode_utf8($key); 
     $in = decode_utf8($in); 
    if($key eq $in) { 
     print "$key: matched\n"; 
    } 
    else { 
     print "Not matched\n"; 
    } 
} 

파일의 줄을 키와 일치 시키려고합니다. 내 코드를 프로파일 링하면 다음과 같은 결과가 나타납니다.

enter image description here

결과 decode_utf8 시간의 34 %를 소비하도록한다. 데이터가 utf8이므로 decode_utf8을 사용했습니다.

여기서 속도를 향상 시키려면 어떻게해야합니까? 코드에서 decode_utf8을 유니 코드 데이터와 일치시키는 다른 해결 방법.

+0

파일 핸들에서 PerlIO 레이어를 사용하는 경우 디코딩이 수행됩니다. ('utf8'은 아무 의미도 없지만, 실제로는 : : encoding (utf8)을 원한다고해도': utf8'을 의미했을 것입니다.) 소스 코드에 유니 코드 문자가 있다면'utf8;을 사용해야합니다. .당신이 필요하지 않다면 전체 파일을 메모리로 읽어서는 안되며, 같은 이름을 가진 배열과 스칼라는 없어야합니다. 왜냐하면 혼란 스럽기 때문입니다. –

+1

그리고 코드에 대한 명백한 어리 석음에도 불구하고 총 실행 시간은 여전히 ​​1 초 미만입니다. 왜 그보다 더 빠를 필요가 있을까요? –

+1

에 대해 자세히 설명하지 않고 decode_utf8에 소요되는 시간을 절반으로 줄일 수 있습니다. 일반적으로 $ key에서 모든 함수를 호출하고 있습니다. 당신은 그것을 루프 밖으로 옮기고 my $ key_decoded = decode_utf8 ($ key)를 사용할 수 있습니다. 루프 내에서 $ key_decoded를 사용하여 $ in과 비교하십시오. – vanHoesel

답변

1

결과 decode_utf8은 34 %의 시간을 소비합니다.

글쎄, 기본적으로 프로그램이하는 모든 것입니다.

더 중요한 것은 코드가 버그입니다. 이전에 디코딩 된 문자열을 디코딩하고 있습니다!

  • 파일을 읽을 때 (:utf8 통해) 파일 내용을 디코딩 한 다음 이미 디코딩 된 내용을 루프에서 디코딩합니다.
  • 루프를 통과 할 때마다 $key의 내용을 디코딩하므로 네 번째 패스에서는 decode_utf8(decode_utf8(decode_utf8(decode_utf8($key))))을 사용합니다.

수정이 너무 다른 문제를 해결

use utf8;        # Source code encoded using UTF-8.  
use open ':std', ':encoding(UTF-8)'; # Term provides and expects UTF-8. Default for files. 

use strict; 
use warnings; 

my $key = "अच्छा"; 

my $found = 0; 
while (my $line = <>) { 
    chomp($line); 
    if ($line eq $key) { 
     $found = 1; 
     last; 
    } 
} 

if ($found) { 
    print "Match found\n"; 
else { 
    print "No match\n"; 
} 

:

  • 는 출력 인코딩 (사용 use open ':std').
  • 불필요하게 전역 변수를 사용하지 않습니다. open IN 대신 open my $IN을 사용하십시오.
  • 불필요하게 전체 파일을 메모리에로드하지 않습니다.
  • 불필요하게 전체 파일을 읽지는 않습니다.
  • Not matched 키가 발견되면 34,999 번 인쇄되지 않습니다.
  • :utf8을 사용하지 않으려면 :encoding(UTF-8)을 사용하십시오.
  • <>을 재발 명하지 마십시오.
  • 줄 중간에 die을 숨기지 않습니다. (or die 앞에 줄 바꿈을하십시오.)
  • "할 수 없습니다"는 사용하지 마십시오. ("사용할 수 없습니다!")
+0

원래 코드의 의도를 변경했습니다. 모든 줄에서'$ key '를 찾지 않고, 전체 파일에서 한 번만 일치시킵니다. –

+0

@Matt Jacob, 당신은 거꾸로 가지고 있습니다. 원래 코드는 버그가있어서 원하는 결과를 생성하는 코드를 생성했습니다. OP가 경기 수를 인쇄하고 싶다고 믿을 이유가 없습니다. 그리고 그랬더라도,'if'는 여전히 루프 외부로 옮겨 져야합니다. ('$ found = 1; last;'를'++ $ found;'로 대체하십시오.) 그리고이 체크가 실제로 루프에 있어야한다면, OP는 이미 그것을하는 법을 알고 있으므로 잃어버린 것이 없습니다. – ikegami

+0

@ikegami 문제를 재현하기 위해 최소한의 검증 가능한 작업 예제를 재현하고 싶었습니다. 따라서 코드가 버그가 있습니다. 사실 모든 것들은 여러 서브 루틴에서 발생합니다. 의도적으로 utf8을 소스 코드에 넣었지만 실제로 변수도 파일에서 할당됩니다. 또한 다른 사용자에게 질문에 대한 설명을 덧붙여 설명을 읽었습니다. – Nagaraju