나는 큰 파일에서 sed를 실행하고 있으며PV입력을 읽고 출력을 쓰는 속도를 확인하는 유틸리티입니다. pv는 약 5초 안에 sed가 입력을 읽고 출력을 쓰는 것을 보여주지만, sed는 20~30초 동안 종료되지 않습니다. 왜 이런거야?
내가 본 결과는 다음과 같습니다.
pv -cN source input.txt | sed "24629045,24629162d" | pv -cN output > output.txt
source: 2.34GB 0:00:06 [ 388MB/s] [==========================================================================================================>] 100%
output: 2.34GB 0:00:05 [ 401MB/s] [ <=> ]
답변1
두 가지 이유가 있습니다. 우선, 당신은 그것을 말하지 않았습니다 q
.
고려하다:
seq 10 | sed -ne1,5p
이 경우 p
입력 라인의 첫 번째 절반만 인쇄하지만 EOF까지 입력 라인의 나머지 부분을 읽어야 합니다. 대신에:
seq 10|sed 5q
즉시 종료됩니다.
또한 각 프로세스 간의 대기 시간도 처리해야 합니다. 따라서 pv
4kb에서 버퍼링하고 sed
4kb를 버퍼링하는 경우 마지막 버퍼는 pv
항상 입력보다 8kb 뒤쳐집니다. 그 수치는 그보다 훨씬 높을 가능성이 높습니다.
-u
GNU/BSD/AST를 사용하여 전환 해 볼 수도 있지만 sed
이는 거의 확실합니다.아니요대규모 입력의 성능을 향상시키는 데 도움이 됩니다. 이를 사용하여 sed
GNU를 호출 하면 입력의 모든 바이트를 대상으로 -u
합니다 read()
. 나는 이 상황에서 다른 사람이 어떻게 할지 본 적이 없지만 그들이 다르게 행동할 것이라고 믿을 이유가 없습니다. 세 파일 모두의 -u
의미버퍼링되지 않은- 이것은 스트림과 관련하여 매우 일반적으로 이해되는 개념입니다.
당신이 할 수 있는 또 다른 일은 명시적인 line-buffer 입니다 sed
.산출w
rite 명령과 하나 이상의 명명된 w
rite-file[s]을 사용합니다 . 여전히 속도는 느려지지만 대안보다 나을 수 있습니다.
sed
다음과 같은 방법으로 이 작업을 수행 할 수 있습니다 .
sed -n 'w outfile'
sed
rite w
명령은 항상 즉각적입니다. 버퍼링되지 않은 출력이 있습니다. 때문에(기본적으로) sed
행 주기당 한 번 명령을 적용하면 sed
파이프라인 도중에도 효율적인 행 버퍼링 I/O를 쉽게 사용할 수 있습니다. 이렇게 하면 최소한 다음 과 같이 pv
두 번째 항목을 항상 최신 상태로 유지할 수 있습니다 sed
.
pv ... | sed -n '24629045,24629162!w /dev/fd/1' | pv ...
/dev/fd/[num]
...링크를 제공하는 시스템이 있다고 가정하더라도(즉, Android를 제외한 거의 모든 Linux 기반 시스템 및다른 많은 것들이 있습니다). 해당 링크를 사용할 수 없는 경우 동일한 작업을 수행하려면 명시적으로 자신만의 파이프를 생성 mkfifo
하고 이를 마지막 rite 파일 pv
의 표준 입력 으로 사용할 수 있습니다 .sed
w