
wc 유틸리티가 왜 그렇게 느린가요?
대용량 파일에서 실행하면 md5sum보다 약 20배 더 오래 걸립니다.
MyDesktop:/tmp$ dd if=/dev/zero bs=1024k count=1024 of=/tmp/bigfile
1024+0 records in
1024+0 records out
1073741824 bytes (1.1 GB) copied, 0.687094 s, 1.6 GB/s
MyDesktop:/tmp$ time wc /tmp/bigfile
0 0 1073741824 /tmp/bigfile
real 0m45.969s
user 0m45.424s
sys 0m0.424s
MyDesktop:/tmp$ time md5sum /tmp/bigfile
cd573cfaace07e7949bc0c46028904ff /tmp/bigfile
real 0m2.520s
user 0m2.196s
sys 0m0.316s
파일이 null로 가득 차서 발생하는 이상한 가장자리 조건이 아니라 파일이 임의의 데이터로 채워져 있거나 텍스트 파일인 경우에도 동일한 성능 차이가 나타납니다.
(우분투 13.04, 64비트에 해당)
답변1
그래서 소스에 가보니 2바이트 문자를 처리하는 데 속도가 느린 것 같습니다. 기본적으로, 읽은 모든 문자에 대해 mbrtowc()
와이드 문자로 변환을 시도하기 위해 호출해야 하며 , 그런 다음 해당 와이드 문자를 테스트하여 단어 구분 기호, 줄 구분 기호 등인지 확인합니다.
LANG
실제로 로케일 변수를 기본값(UTF-8은 멀티바이트 문자 집합)에서 변경 하고 " "(간단한 단일 바이트 문자 집합) en_US.UTF-8
로 설정하면 은(는) 단일 바이트 최적화를 사용할 수 있어 속도가 상당히 빨라집니다. 이전보다 약 1/4 정도만 소요됩니다.C
wc
-w
또한 단어( ), 줄 길이( -L
) 또는 문자( ) 계산을 수행하는 경우 각 문자만 확인하면 됩니다 -m
. 바이트 및/또는 줄 수만 계산하는 경우 와이드 문자 처리를 건너뛸 수 있으며 md5sum
.
를 통해 실행해 보았는데 , 멀티바이트 문자( , , 등) gprof
를 처리하는 데 사용되는 함수가 실행 시간의 약 30% 정도를 차지하고 있고, 버퍼를 거쳐가는 코드는 훨씬 더 복잡합니다. 가변 크기 문자에 대해 버퍼를 통해 가변 크기 단계를 처리할 뿐만 아니라 다음 번에 처리할 수 있도록 버퍼를 다시 버퍼의 시작 부분까지 확장하는 부분적으로 완료된 문자를 채웁니다.mymbsinit()
mymbrtowc()
myiswprint()
이제 무엇을 찾아야 할지 알았으므로 일부 유틸리티의 utf-8 속도 저하를 언급하는 몇 가지 게시물을 발견했습니다.
https://stackoverflow.com/questions/13913014/grepping-a-huge-file-80gb-any-way-to-speed-it-up http://dtrace.org/blogs/brendan/2011/12/08/2000x-performance-win/
답변2
wc
단지 추측일 뿐이지만 현재 하고 있는 일과 현재 하고 있는 일 에 관해 사과와 오렌지를 비교하고 있는 것입니다 md5sum
.
md5sum의 작업
파일을 처리할 때 md5sum
파일을 스트림으로 연 다음 스트림을 통해 스트림 실행을 시작합니다.MD5 체크섬 기능메모리가 거의 필요하지 않습니다. 본질적으로 CPU 및 디스크 I/O에 바인딩됩니다.
화장실의 임무
실행될 때 wc
파일을 한 번에 한 문자씩 구문 분석하는 것보다 훨씬 더 많은 작업을 수행합니다. 문자 사이의 경계가 어디에 있는지, 단어 경계인지 아닌지를 결정하면서 한 번에 한 줄씩 파일의 구조를 분석해야 합니다.
예
다음 문자열을 생각하고 각 알고리즘이 문자열을 구문 분석할 때 어떻게 이동해야 하는지 생각해 보세요.
“Hello! Greg”
“Hello!Greg”
“Hello\nGreg”
“A.D.D.”
“Wow, how great!”
“wow \n\n\n great”
“it was a man-eating shark.”
MD5의 경우 이러한 문자열을 한 번에 한 문자씩 간단하게 이동합니다. 왜냐하면 wc
단어와 줄 경계가 무엇인지 결정하고 표시되는 발생 횟수를 추적해야 하기 때문입니다.
추가 화장실 토론
나는 이것을 찾았다2006년 코딩챌린지.NET에서의 구현에 대해 설명합니다 wc
. 일부 의사 코드를 살펴보면 어려움이 매우 분명하므로 wc
다른 작업보다 훨씬 느린 이유를 밝히는 데 도움이 될 수 있습니다 .