서브쉘 사용에 따른 오버헤드는 무엇입니까?

서브쉘 사용에 따른 오버헤드는 무엇입니까?

이 질문이 너무 일반적인 질문은 아니길 바랍니다. 저는 쉘 스크립팅을 처음 접했고 컴퓨터 아키텍처/비스크립팅 프로그래밍 경력을 갖고 있습니다. 나는 내 작업의 스크립트에서 전체 스크립트 주위에 하위 쉘을 만들어 스크립트를 작성하는 경우가 거의 없음을 확인했습니다. 내가 작성하고 있는 스크립트에서 하위 셸로 이를 포함할 수 있는 이유는 하위 셸이 내 것을 호출하는 다른 스크립트와 혼동되는 것을 방지하기 때문입니다(만일의 경우). 이 접근 방식과 관련된 일부 오버헤드 때문에 이는 일반적인 관행이 아닙니까? 나는 이것을 온라인에서 찾는 데 어려움을 겪고 있습니다.

예:

#!/bin/bash
( #Start of subshell
echo "Some stuff here"
) #End of subshell

답변1

서브쉘에는 오버헤드가 있습니다.

내 시스템에서 최소 포크 실행 비용(파일이 콜드되지 않은 상태에서 디스크에서 프로그램을 실행할 때)은 약 2ms이고 최소 포크 비용은 약 입니다 1ms.

서브쉘을 사용하면 파일을 편집할 필요가 없으므로 포크 비용만 이야기하는 것입니다 exec. 서브쉘이 합리적으로 낮게 유지되면 1ms인간을 대상으로 하는 프로그램에서는 매우 무시할 수 있습니다. 나는 인간이 더 빠르게 일어나는 일을 알아차릴 수 없다고 믿습니다 50ms. (그리고 그것은 현대 스크립팅 언어 통역사가 최신 작업을 시작하는 데 (여기서는 python루비라고 말하고 있습니다 rvm)) 시작하는 데 걸리는 시간입니다 .nodejs100ms

그러나 루프가 추가되고 예를 들어 함수에서 무언가를 $()가져오는 다소 일반적인 백틱이나 패턴을 표준 출력으로 인쇄하여 상위 쉘이 bashism과 같은 것으로 캡처하도록 대체할 수 있습니다 (또는 빠른 외부 전체 배치를 처리하는 프로그램).returnprintf -v

그만큼bash 완성패키지는 다음에 설명된 기술을 사용하여 전달된 변수 이름을 통해 반환함으로써 이 서브셸 비용을 특별히 방지합니다.http://fvue.nl/wiki/Bash:_Passing_variables_by_reference


비교

time for((i=0;i<10000;i++)); do echo "$(echo hello)"; done >/dev/null 

~와 함께

time for((i=0;i<10000;i++)); do echo hello; done >/dev/null 

fork시스템 오버헤드가 무엇인지에 대한 좋은 추정치를 제공해야 합니다 .

답변2

내 시스템에서 PSkocik이 제공한 뛰어난 코드를 실행해도 무시할 만한 결과가 나타났습니다.

그러나 이 예제는 실제로 기본 명령과 하위 쉘 명령을 비교하여 적용됩니다.

MyPath="path/name.ext" 
# this takes forever
time for((i=0;i<10000;i++)); do echo "$(basename ${MyPath} )"; done >/dev/null 
#this is over 100x less time 
time for((i=0;i<10000;i++)); do echo "${MyPath##*/}"; done >/dev/null     

관련 정보