[첫화면으로]"Perl/Archive-Zip" 페이지의 변경 내역

마지막으로 [b]


현재 버전 . . . . 2013-12-20 5:52 pm 수정한 사람: Raymundo [실험4 추가]
11 번째 수정본 . . . . 2013-12-20 5:46 pm 수정한 사람: Raymundo
10 번째 수정본 . . . . 2013-12-20 5:40 pm 수정한 사람: Raymundo
9 번째 수정본 . . . . 2013-12-20 5:39 pm 수정한 사람: Raymundo ["반복적인 read() 호출과 extract() 관련 문제점" 섹션 정리]
8 번째 수정본 . . . . 2013-12-20 5:35 pm 수정한 사람: Raymundo [실험3 - ]
7 번째 수정본 . . . . 2013-12-20 5:35 pm 수정한 사람: Raymundo [실험2 - ]
6 번째 수정본 . . . . 2013-12-20 5:35 pm 수정한 사람: Raymundo
5 번째 수정본 . . . . 2013-12-20 5:34 pm 수정한 사람: Raymundo
4 번째 수정본 . . . . 2013-12-20 5:16 pm 수정한 사람: Raymundo [read()와 extract()관련 버그 - ]
3 번째 수정본 . . . . 2013-12-20 5:04 pm 수정한 사람: Raymundo
2 번째 수정본 . . . . 2013-12-20 5:02 pm 수정한 사람: Raymundo [버그? - ]
1 번째 수정본 . . . . 2013-12-20 12:45 am 수정한 사람: Raymundo
 

변경사항 (가장 최근의 "일반적인 수정"부터) (다른 변경사항 없음)

-301,6 +301,107
* '''메모리 사용량이 실험2와 동일하게 늘었다'''.
=== # 실험4 - 매번 객체 만들기 ===
생각해보니까, 정작 이 테스트를 빼먹었다. 루프를 2만 번 돌면서 매번 Archive::Zip 객체를 새로 생성해서 사용하자.
{{{#!vim perl
for my $num ( 1 .. 20000 ) {
    # Archive::Zip 오브젝트를 매번 생성
    my $zip = Archive::Zip->new();
    # 압축 파일을 매번 읽고
    $zip->read($file);
    # 특정 파일을 추출
    $zip->extractMemberWithoutPaths($member);
}
}}}
<memo(전체 코드 - 길어서 감춤)>
{{{#!vim perl
#!/usr/bin/env perl
use strict;
use warnings;
# local $| = 1;
use Archive::Zip qw/:ERROR_CODES :CONSTANTS/;
use Time::HiRes qw/gettimeofday tv_interval/;
use Memory::Usage;
my $member = 'LIST.txt';  # ZIP 파일 내에서 꺼낼 파일
my $file = '/home/gypark/temp/gearman/data/00001.zip';
my $mu = Memory::Usage->new;
my $time_read = 0;
my $time_extract = 0;
my $t0;
my $elapsed;
$mu->record('before loop');
for my $num ( 1 .. 20000 ) {
    # Archive::Zip 오브젝트를 매번 생성
    my $zip = Archive::Zip->new();
    # 압축 파일을 매번 읽고
    $t0 = [ gettimeofday ];
    $zip->read($file);
    $elapsed = tv_interval($t0);
    $time_read += $elapsed;
    # 특정 파일을 추출
    $t0 = [ gettimeofday ];
    $zip->extractMemberWithoutPaths($member);
    $elapsed = tv_interval($t0);
    $time_extract += $elapsed;
    if ( $num % 1000 == 0 ) {
        printf("%d, %.6f, %.6f\n", $num, $time_read/1000, $time_extract/1000);
        $time_read = 0;
        $time_extract = 0;
    }
    # 추출했던 파일은 삭제
    unlink $member or die "unlink:$!";
}
$mu->record('after loop');
$mu->dump();
}}}
</memo>
결과:
{{{
1000, 0.000419, 0.000705
2000, 0.000361, 0.000610
3000, 0.000412, 0.000692
4000, 0.000428, 0.000721
5000, 0.000457, 0.000770
6000, 0.000459, 0.000787
7000, 0.000475, 0.000797
8000, 0.000421, 0.000705
9000, 0.000428, 0.000721
10000, 0.000424, 0.000715
11000, 0.000418, 0.000706
12000, 0.000439, 0.000735
13000, 0.000388, 0.000636
14000, 0.000478, 0.000790
15000, 0.000456, 0.000777
16000, 0.000433, 0.000727
17000, 0.000425, 0.000721
18000, 0.000322, 0.000543
19000, 0.000392, 0.000655
20000, 0.000395, 0.000665
  time    vsz (  diff)    rss (  diff) shared (  diff)   code (  diff)   data (  diff)
     0  94872 ( 94872)   8884 (  8884)   2036 (  2036)   1412 (  1412)   7140 (  7140) before loop
    24  94872 (     0)   8976 (    92)   2096 (    60)   1412 (     0)   7140 (     0) after loop
}}}
* read() 시간도 일정
* extract() 시간도 일정
* 메모리도 별다른 누수는 없는 걸로 보임
* 매번 객체를 생성하는 오버헤드는 어쩔 수 없이 있겠지만, 전체 실행 시간을 생각하면 훨씬 이득이다. (24초 정도 걸렸음)
=== # 중간 결론 ===
* read()가 압축 파일을 읽을 때 기존에 읽었던 메모리를 제대로 반납하지 않는지, read()를 할 때마다 메모리를 차지함