따라서 일반적으로 sed
텍스트 처리, 특히 큰 파일의 경우에는 쉘 자체에서 이런 종류의 작업을 수행하지 않는 경향이 있습니다.
그래도 변경 될 수 있다고 생각합니다. 나는 주변을 파고 man ksh
있었고 이것을 발견했습니다.
<#pattern Seeks forward to the beginning of the
next line containing pattern.
<##pattern The same as <# except that the por‐
tion of the file that is skipped is
copied to standard output.
실제 유용성에 회의적으로, 나는 그것을 시도하기로 결정했습니다. 나는했다 :
seq -s'foo bar
' 1000000 >file
… 다음과 같은 백만 줄의 데이터 :
1foo bar
...
999999foo bar
1000000
… 그리고 다음과 sed
같이 반대했습니다 .
p='^[^0-8]99999.*bar'
for c in "sed '/$p/q'" "ksh -c ':<##@(~(E)$p)'"
do </tmp/file eval "time ( $c )"
done | wc -l
따라서 두 명령 모두 최대 999999foo bar가 되어야하며 패턴 일치 구현은 최소한 각 행의 시작과 끝을 평가해야합니다. 또한 부정 된 패턴에 대해 첫 번째 문자를 확인해야합니다. 이것은 간단한 일이지만 … 결과는 내가 기대 한 것이 아닙니다.
( sed '/^[^0-8]99999.*bar/q' ) \
0.40s user 0.01s system 99% cpu 0.419 total
( ksh -c ':<##@(~(E)^[^0-8]99999.*bar)' ) \
0.02s user 0.01s system 91% cpu 0.033 total
1999997
ksh
여기서 ERE와 sed
BRE를 사용합니다. 나는 ksh
전에와 셸 패턴으로 같은 일을 했지만 결과는 다르지 않았습니다.
어쨌든, 그것은 매우 중요한 차이입니다 – ksh
성능이 뛰어을 sed
10 회 이상. David Korn은 자신의 io lib를 작성하여 구현하기 전에 읽었습니다. ksh
아마도 관련이 있습니까? -그러나 나는 그것에 대해 아무것도 알지 못한다. 껍질이 어떻게 그렇게 잘합니까?
나에게 더 놀라운 것은 ksh
실제로 당신이 그것을 요구하는 곳에 오프셋을 남겨 두는 것입니다. 얻으려면 (거의) 같은 아웃 (GNU)를 sed
당신은 사용해야합니다 -u
– 매우 느린 .
다음은 grep
V. ksh
테스트입니다.
1000000 #grep + head
( grep -qm1 '^[^0-8]99999.*bar'; head -n1; ) \
0.02s user 0.00s system 90% cpu 0.026 total
999999foo bar #ksh + head
( ksh -c ':<#@(~(E)^[^0-8]99999.*bar)'; head -n1; ) \
0.02s user 0.00s system 73% cpu 0.023 total
ksh
grep
여기에 이길 수 있지만 항상 그런 것은 아닙니다. 그럼에도 불구하고, 그것은 꽤 좋은입니다, 그리고 ksh
내다 제공 – head
의 입력을 시작 하기 전에 의 일치합니다.
사실 너무 좋은 것 같아요. 이 명령들은 후드에서 어떻게 다르게 작동합니까?
아, 그리고 분명히 여기에도 서브 쉘이 없습니다 :
ksh -c 'printf %.5s "${<file;}"'
답변
ksh는 sfio를 사용할 뿐만 아니라 자체 커스텀 메모리 할당자를 사용합니다.
그럼에도 불구하고, 내 생각에 sfio는이 경우에 차이를 만듭니다. 방금 strace에서 예제를 실행하려고 시도했으며 ksh가 ~ 200 번 (65 KB 블록) 읽기 / 쓰기를하는 동안 sed가 ~ 3400 번 (4 KB 블록)을 수행한다는 것을 알 수 있습니다. sed -u 내 랩톱이 거의 녹 으면 바이트 당 읽기가 수행되고 라인 당 쓰기가 수행됩니다. Ksh simple은 lseek를 사용합니다. Grep은 ~ 400 회 읽기 (32KB 블록)를 사용합니다.