[첫화면으로]Perl/불필요한일을시키지말라

마지막으로 [b]

원래 있던 코드: 각 라인을 읽고 탭을 기준으로 분리한 후, 4번째,6번째 필드를 수정하여 출력
while (<>) {
  chomp;
  my @x = split "\t";
  $x[3] = lc $x[3];
  $x[5] = uc $x[5];
  print join("\t", @x), "\n";
}

위 코드는 매 라인에 chomp를 수행하고 출력할 때 다시 \n을 덧붙이고 있다. 불필요하다.
while (<>) {
  my @x = split "\t";
  $x[3] = lc $x[3];
  $x[5] = uc $x[5];
  print join("\t", @x);
}

여기서는 6번째 필드까지만 의미가 있기 때문에, 각 라인의 나머지 부분을 굳이 분리할 필요가 없다. split 에 인자를 추가로 주어서 7개의 필드로만 분리한다.
while (<>) {
  my @x = split "\t", $_, 7;
  $x[3] = lc $x[3];
  $x[5] = uc $x[5];
  print join("\t", @x);
}

만일 수정할 필드를 사전에 미리 각 라인의 앞부분으로 옮겨놓을 수 있었다면, 3개의 필드로만 분리해도 된다
while (<>) {
  my @x = split "\t", $_, 3;
  $x[0] = lc $x[0];
  $x[1] = uc $x[1];
  print join("\t", @x);
}

벤치마크: 100개 필드로 이뤄진 라인 10,000 줄에 대하여 각각의 방법을 적용
use warnings;
use strict;
use Benchmark qw(timethese);

my @data;

for (0..10_000) {
  $data[$_] = join "\t", map { chr(65 + (int rand(52))) } (0..100);
}

timethese(500, {
  'standard' => sub {
    for (@data) {
      chomp;
      my @x = split "\t";
      $x[3] = lc $x[3];
      $x[5] = uc $x[5];
      $_ = join("\t", @x) . "\n";
    }
  },
  'no_chomp' => sub {
    for (@data) {
      my @x = split "\t";
      $x[3] = lc $x[3];
      $x[5] = uc $x[5];
      $_ = join("\t", @x);
    }
  },
  'smaller' => sub {
    for (@data) {
      my @x = split "\t", $_, 7;
      $x[3] = lc $x[3];
      $x[5] = uc $x[5];
      $_ = join("\t", @x);
    }
  },
  'smallest' => sub {
    for (@data) {
      my @x = split "\t", $_, 3;
      $x[0] = lc $x[0];
      $x[1] = uc $x[1];
      $_ = join("\t", @x);
    }
  },
});

결과: split 의 범위를 제한하는 것이 매우 큰 효과가 있다.
Benchmark: timing 500 iterations of no_chomp, smaller, smallest, standard…
standard: 451 wallclock secs (449.66 usr + 0.34 sys = 450.00 CPU) @ 1.11/s (n=500)
no_chomp: 451 wallclock secs (446.18 usr + 0.41 sys = 446.59 CPU) @ 1.12/s (n=500)
smaller: 39 wallclock secs (39.15 usr + 0.03 sys = 39.18 CPU) @ 12.76/s (n=500)
smallest: 19 wallclock secs (18.98 usr + 0.01 sys = 18.99 CPU) @ 26.33/s (n=500) 

필드 개수가 10개일 때의 결과: 필드의 개수가 적을 때는 차이가 다소 덜하지만 여전히 효과가 있다.
enchmark: timing 500 iterations of no_chomp, smaller, smallest, standard…
standard: 58 wallclock secs (57.50 usr + 0.05 sys = 57.55 CPU) @ 8.69/s (n=500)
no_chomp: 55 wallclock secs (55.13 usr + 0.04 sys = 55.17 CPU) @ 9.06/s (n=500)
smaller: 38 wallclock secs (37.67 usr + 0.03 sys = 37.70 CPU) @ 13.26/s (n=500)
smallest: 18 wallclock secs (18.46 usr + 0.01 sys = 18.47 CPU) @ 27.07/s (n=500) 

결론: 성능을 고려한다면, 할 필요가 없는 작업을 코드가 수행하지 않도록 하라.

음.. 불필요한 걸 시키지 말라는 게 귀찮은 거 시키지 말라는 듯 하고..
꼭 마누라에게 말하는 것 같소.. ㅎㅎㅎ
-- Zehn02 2010-8-10 8:10 pm

푸하, 뭐 불필요한 일을 굳이 하지 않는 게 좋다는 건 컴퓨터나 사람이나 마찬가지니까... 다만 불필요한지 아닌지를 판단하는 기준이 좀 더 복잡해질 뿐.
-- Raymundo 2010-8-10 11:26 pm
이름:  
Homepage:
내용:
 


컴퓨터분류

마지막 편집일: 2012-2-11 12:25 am (변경사항 [d])
1340 hits | Permalink | 변경내역 보기 [h] | 페이지 소스 보기