7.6GB gzip 파일에 대한 레코드 카운팅을 시도하고 있습니다. zcat
이 명령을 사용하는 방법은 거의 없습니다 .
$ zcat T.csv.gz | wc -l
423668947
이 방법은 작동하지만 시간이 너무 많이 걸립니다(계산하는 데 10분 이상). 나는 다음과 같은 더 많은 방법을 시도했습니다.
$ sed -n '$=' T.csv.gz
28173811
$ perl -lne 'END { print $. }' < T.csv.gz
28173811
$ awk 'END {print NR}' T.csv.gz
28173811
세 가지 명령 모두 매우 빠르게 실행되지만 잘못된 개수인 28173811이 표시됩니다.
최소 시간에 레코드 계산을 수행하는 방법은 무엇입니까?
답변1
언급 한 sed
, perl
및 명령은 awk
정확할 수 있지만 모두 읽습니다.압축데이터를 입력하고 그 안에 개행 문자를 세어보세요. 이러한 줄 바꿈은 압축되지 않은 데이터의 줄 바꿈과 독립적입니다.
압축되지 않은 데이터의 행 수를 계산하려면 압축을 풀 수 없습니다. 귀하의 접근 방식이 zcat
올바른 접근 방식이며 데이터가 너무 크기 때문에~ 할 것이다포장을 푸는 데 시간이 좀 걸립니다.
압축 및 압축 해제를 처리하는 대부분의 유틸리티는 gzip
이를 수행하기 위해 동일한 공유 라이브러리 루틴을 사용할 가능성이 높습니다. 작업 속도를 높이는 유일한 방법은 zlib
기본 루틴보다 더 빠른 루틴 구현을 찾고 zcat
이를 사용하기 위해 다시 빌드하는 것입니다.
답변2
unpigz를 사용하세요.
Kosalonanda의 대답이 맞습니다.~ 할 것이다내용을 스캔하려면 먼저 전체 파일의 압축을 풀어야 합니다. /bin/gunzip
단일 코어에서 가능한 한 빨리 이 작업을 수행합니다.돼지 돼지gzip
여러 코어를 사용할 수 있는 병렬 구현입니다.
pigz
안타깝게도 일반 gzip 파일 자체의 압축 풀기는 병렬화할 수 없지만 읽기, 쓰기, 체크섬과 같은 관련 작업을 별도의 스레드에서 수행하는 개선된 버전의 gzip을 제공합니다 . 일부 빠른 벤치마크에서는 코어 i5 시스템보다 거의 두 배 빠른 속도입니다.gunzip
unpigz
unpigz
gunzip
pigz
선호하는 패키지 관리자를 사용하여 설치하고 대신 unpigz
사용 하십시오 gunzip
. 따라서 귀하의 명령은 다음과 같습니다.unpigz -c
zcat
$ unpigz -c T.csv.gz | wc -l
물론 이 모든 것은 병목 현상이 디스크가 아닌 CPU라고 가정합니다.
답변3
모든 배관의 문제는 기본적으로 작업량이 두 배로 늘어난다는 것입니다. 압축 해제 속도에 관계없이 데이터는 여전히 다른 프로세스로 이동되어야 합니다.
Perl은PerlIO::gzipgzip으로 압축된 스트림을 직접 읽을 수 있습니다. 따라서 감압 속도가 일치하지 않더라도 다음과 같은 이점이 있을 수 있습니다 unpigz
.
#!/usr/bin/env perl
use strict;
use warnings;
use autouse Carp => 'croak';
use PerlIO::gzip;
@ARGV or croak "Need filename\n";
open my $in, '<:gzip', $ARGV[0]
or croak "Failed to open '$ARGV[0]': $!";
1 while <$in>;
print "$.\n";
close $in or croak "Failed to close '$ARGV[0]': $!";
13MB gzip 압축 파일(1.4GB로 압축 해제)이 있는 오래된 컴퓨터에서 시도해 보았습니다.16GB RAM을 갖춘 2010년 MacBook Pro그리고 오래된 것ThinkPad T400에는 8GB RAM이 탑재되어 있습니다.파일이 이미 캐시에 있습니다. Mac에서 Perl 스크립트는 파이프를 사용하는 것보다 훨씬 빠르지만(5초 대 22초) ArchLinux에서는 unpigz에 패배합니다.
$ 시간 -p ./gzlc.pl spy.gz 1154737 실제 4.49 사용자 4.47 시스템 0.01
비교적
$ 시간 -p unpigz -c spy.gz 화장실 -l | 1154737 실제 3.68 사용자 4.10 시스템 1.46
그리고
$ 시간 -p zcat spy.gz 화장실 -l | 1154737 레알 6.41 사용자 6.08 시스템 0.86
분명히 unpigz -c file.gz | wc -l
속도 측면에서 사용량이 승자입니다. 그리고 아무리 짧더라도 간단한 명령줄은 확실히 프로그램 작성보다 낫습니다.
답변4
이는 zgrep
플래그 -c
와 $
매개변수를 사용하여 수행할 수 있습니다.
이 경우 -c는 명령 출력에 줄 수를 일치시키도록 지시하고 정규식 $는 줄 끝과 일치하므로 모든 줄이나 파일과 일치합니다.
zgrep -c $ T.csv.gz
@StéphaneChazelas가 언급한 대로 - 원래 제안과 유사한 성능을 제공해야 하는 스크립트 zgrep
일 뿐입니다.zcat
grep
zcat | wc -l