파일의 각 줄을 "읽는" 것이 "xargs"보다 훨씬 빠른 이유

파일의 각 줄을 "읽는" 것이 "xargs"보다 훨씬 빠른 이유

나는 30M 줄을 포함하는 큰 입력 파일을 가지고 있습니다 \r\n. 나는 어리석은 일을 하고 read -r모든 줄을 계산하는 속도를 비교하기로 결정했습니다( 두 문자 이상을 분할하는 것이 불가능해 보이기 때문에 xargs첫 번째 줄을 제거 ). 내 두 명령은 다음과 같습니다.\rxargs

time tr -d '\r' < input.txt | xargs -P 1 -d '\n' -I {} echo "{}" | wc -l
time while read -r p || [ -n "$p" ]; do echo "$p"; done < input.txt | wc -l

여기서 두 번째 해결책은많은서둘러요. 왜 그런 겁니까?

나는 이것이 파일의 줄 수를 계산하는 올바른 방법이 아니라는 것을 알고 있습니다. 이 질문은 단지 나의 관찰적 관심에서 나온 것입니다.

답변1

예, 예상한 대로 이는 실제로 xargs -P 1 -d '\n' -I {} echo "{}"프로세스를 분기하고 각 입력 줄에 대해 상위 프로세스에서 종료될 때까지 기다리는 동안 하위 프로세스에서 독립적인 프로세스를 실행하는 기본 명령과 동일합니다.xargs -rd '\n' -n1echoecho

따라서 이는 동일한 쉘 프로세스에서 비효율적인 내장 기능과 모든 내장 기능을 사용하는 것보다 read훨씬 더 많은 작업입니다 .echo

xargsxargs(적어도 일부 구성 및 최신 버전에서는) 프로세스를 분기하지 않고 내부적으로 busybox를 호출 하는 GNU 대신 busybox를 사용하면 루프보다 훨씬 빠르다 echo는 것을 알 수 있습니다 .bash

보다 관련성이 높은 비교를 위해서는 다음을 비교해야 합니다.

tr -d '\r' | xargs -rd'\n' -n1

그리고

tr -d '\r' |
  while IFS= read -r line || [ -n "$line" ]; do
   /bin/echo "$line"
  done

대부분의 시간이 프로세스를 분기하고 독립적으로 실행하는 데 소비되므로 비슷한 결과를 얻을 수 있습니다 echo.

여기에서 출력 seq 3e7및 측정 pv -al > /dev/null( a초당 평균 라인으로 측정된 처리량)과 관련하여 해결책을 얻었습니다.l

  • busybox xargs는 1.12M/s입니다.
  • 70k/s의 에코가 내장된 bash 루프
  • GNU xargs는 860/s입니다.
  • /bin/echo를 사용한 bash 루프의 경우 850/s

관련 정보