이 페이지에서 제안한 솔루션을 벤치마킹 할 수있는 독특한 상황이 있으므로이 답변을 각 솔루션에 대한 런타임이 포함 된 제안 솔루션의 통합으로 작성하고 있습니다.
설정
행당 하나의 키-값 쌍을 가진 3.261 기가 바이트 ASCII 텍스트 데이터 파일이 있습니다. 파일에는 총 3,339,550,320 행이 포함되어 있으며 Vim으로 이동하는 것을 포함하여 시도한 모든 편집기에서 열리지 않습니다. 발견 한 일부 값을 조사하려면 ~ 500,000,000 행 정도에서 시작해야합니다.
파일에 행이 너무 많기 때문에 :
- 데이터에 유용한 작업을 수행하려면 행의 하위 집합 만 추출하면됩니다.
- 내가 관심을 갖는 가치로 이어지는 모든 행을 읽는 데는 오랜 시간이 걸릴 것입니다.
- 솔루션이 내가 관심있는 행을지나 읽고 나머지 파일을 계속 읽는 경우 거의 30 억 개의 관련 행을 읽는 데 시간을 낭비하고 필요한 것보다 6 배 더 오래 걸립니다.
가장 좋은 시나리오는 파일의 다른 행을 읽지 않고 파일에서 한 줄만 추출하는 솔루션이지만 Bash 에서이 작업을 수행하는 방법을 생각할 수 없습니다.
내 정신 건강을 위해 나는 내 자신의 문제에 필요한 500,000,000 줄 전체를 읽으려고하지 않을 것입니다. 대신 3,339,550,320에서 50,000,000 행을 추출하려고 시도합니다 (전체 파일을 읽는 데 필요한 시간보다 60 배 더 오래 걸립니다).
time
내장 명령을 사용하여 각 명령을 벤치마킹 할 것입니다.
베이스 라인
먼저 head
tail
솔루션이 어떻게 작동하는지 봅시다 :
$ time head -50000000 myfile.ascii | tail -1
pgm_icnt = 0
real 1m15.321s
5 천만 행의 기준선은 00 : 01 : 15.321입니다. 5 억 행에 대해 직진하면 아마 ~ 12.5 분이됩니다.
절단
나는 이것에 대해 의심 스럽다. 그러나 그것은 가치가있다.
$ time cut -f50000000 -d$'\n' myfile.ascii
pgm_icnt = 0
real 5m12.156s
이것은 실행하는 데 00 : 05 : 12.156이 걸렸으며 이는 기준선보다 훨씬 느립니다! 중지하기 전에 전체 파일을 읽거나 5 천만 줄까지 읽었는지 확실하지 않지만 이것이 문제에 대한 실용적인 해결책처럼 보이지는 않습니다.
AWK
exit
전체 파일이 실행될 때까지 기다리지 않기 때문에 솔루션 만 실행했습니다 .
$ time awk 'NR == 50000000 {print; exit}' myfile.ascii
pgm_icnt = 0
real 1m16.583s
이 코드는 00 : 01 : 16.583에서 실행되었는데, 이는 ~ 1 초 느리지 만 여전히 기준선의 개선은 아닙니다. 종료 명령이 제외 된 경우이 속도로 전체 파일을 읽는 데 약 ~ 76 분이 걸렸을 것입니다!
펄
기존 Perl 솔루션도 실행했습니다.
$ time perl -wnl -e '$.== 50000000 && print && exit;' myfile.ascii
pgm_icnt = 0
real 1m13.146s
이 코드는 00 : 01 : 13.146에서 실행되었으며 기준보다 2 초 빠릅니다. 전체 500,000,000에서 실행하면 ~ 12 분이 걸릴 것입니다.
sed
보드의 최고 답변은 다음과 같습니다.
$ time sed "50000000q;d" myfile.ascii
pgm_icnt = 0
real 1m12.705s
이 코드는 00 : 01 : 12.705에서 실행되었는데, 이는 기준선보다 3 초 빠르며 Perl보다 ~ 0.4 초 빠릅니다. 전체 500,000,000 행에서 실행하면 ~ 12 분이 걸렸을 것입니다.
맵 파일
bash 3.1이있어 맵 파일 솔루션을 테스트 할 수 없습니다.
결론
대부분 head
tail
솔루션 을 개선하기가 어려운 것처럼 보입니다 . 기껏해야sed
솔루션은 ~ 3 %의 효율성 향상을 제공합니다.
(공식으로 계산 한 백분율 % = (runtime/baseline - 1) * 100
)
50,000,000 행
- 00 : 01 : 12.705 (-00 : 00 : 02.616 = -3.47 %)
sed
- 00 : 01 : 13.146 (-00 : 00 : 02.175 = -2.89 %)
perl
- 00 : 01 : 15.321 (+00 : 00 : 00.000 = + 0.00 %)
head|tail
- 00 : 01 : 16.583 (+00 : 00 : 01.262 = + 1.68 %)
awk
- 00 : 05 : 12.156 (+00 : 03 : 56.835 = + 314.43 %)
cut
행 500,000,000
- 00 : 12 : 07.050 (-00 : 00 : 26.160)
sed
- 00 : 12 : 11.460 (-00 : 00 : 21.750)
perl
- 00 : 12 : 33.210 (+00 : 00 : 00.000)
head|tail
- 00 : 12 : 45.830 (+00 : 00 : 12.620)
awk
- 00 : 52 : 01.560 (+00 : 40 : 31.650)
cut
3,338,559,320 열
- 01 : 20 : 54.599 (-00 : 03 : 05.327)
sed
- 01 : 21 : 24.045 (-00 : 02 : 25.227)
perl
- 01 : 23 : 49.273 (+00 : 00 : 00.000)
head|tail
- 01 : 25 : 13.548 (+00 : 02 : 35.735)
awk
- 05 : 47 : 23.026 (+04 : 24 : 26.246)
cut
awk
과sed
나는 누군가가 그렇게뿐만 아니라 펄 한 줄을 마련하거나 할 수 있습니다 확신)