Bash 스크립트를 최적화하기 위한 일반적인 지침이 있는지 궁금합니다.
예를 들어, 그것은 더편리한명령줄 대신 루프를 작성하지만, 이는 또한더 빠른 처리시스템을 위해서? 예:
for i in a b c; do echo $i; done echo a echo b echo c
때때로 사람들은 동일한 문제에 대해 서로 다른 해결책을 생각해냅니다. 예를 들어,
sed
,cut
및awk
는echo
모두 문자열에서 숫자를 제거할 수 있습니다. 다음 코드를 사용하면 숫자가 낮을수록 속도가 빨라진다고 말할 수 있는지 궁금합니다.같은 명령
STRING=abc.def echo ${STRING} | sed 's/.def//g' echo ${STRING} | sed '$s/....$//'
다음과 같은 다른 명령
STRING=abc.def echo ${STRING} | cut -d . -f 1 echo ${STRING} | sed 's/.def//g'
답변1
최적화의 첫 번째 규칙은 다음과 같습니다.최적화되지 않음. 먼저 테스트해보세요. 테스트 결과 프로그램이 너무 느린 것으로 나타나면 가능한 최적화 방법을 찾아보세요.
확실히 알 수 있는 유일한 방법은 사용 사례를 벤치마킹하는 것입니다. 몇 가지 일반적인 규칙이 있지만 일반적인 애플리케이션의 일반적인 데이터 양에만 적용됩니다.
특정 상황에서는 일부 일반 규칙이 적용되거나 적용되지 않을 수 있습니다.
- 셸 내부 처리의 경우 ATT ksh가 가장 빠릅니다. 문자열 조작을 많이 한다면 ATT ksh를 사용하세요. Dash가 2위이고 bash, pdksh 및 zsh가 뒤쳐져 있습니다.
- 한 번에 짧은 작업을 수행하기 위해 셸을 자주 호출해야 하는 경우 시작 시간이 짧기 때문에 대시가 승리합니다.
- 외부 프로세스를 시작하는 데는 시간이 걸리므로 복잡한 부분이 포함된 파이프라인을 갖는 것이 루프의 파이프라인보다 빠릅니다.
echo $foo
echo "$foo"
큰따옴표가 없으면$foo
단어로 나누어 각 단어를 파일 이름 와일드카드 패턴으로 해석하기 때문에 그보다 느립니다 . 게다가 이러한 분할 및 와일드카드 동작은 거의 필요하지 않습니다. 따라서 변수 대체 및 명령 대체에는 항상 큰따옴표를 넣어야 한다는 점을 기억하십시오:"$foo"
,"$(foo)"
.- 특수 목적 도구는 종종 범용 도구보다 성능이 뛰어납니다. 예를 들어,
cut
또는 같은 도구를head
사용하여 시뮬레이션할 수 있지만sed
속도sed
가 느려지거나 더 느려집니다awk
. 쉘 문자열 처리는 느리지만 짧은 문자열의 경우 외부 프로그램을 호출하는 것보다 성능이 훨씬 뛰어납니다. - Perl, Python 및 Ruby와 같은 고급 언어를 사용하면 더 빠른 알고리즘을 작성할 수 있는 경우가 많지만 시작 시간이 훨씬 길기 때문에 많은 양의 데이터로 작업하는 경우에만 수행할 가치가 있습니다.
- 적어도 Linux에서는 파이프가 임시 파일보다 빠른 경향이 있습니다.
- 쉘 스크립트의 대부분의 사용은 I/O 집약적인 프로세스를 중심으로 이루어지므로 CPU 소비는 중요하지 않습니다.
성능 문제는 쉘 스크립트에서 거의 고려되지 않습니다.위 목록은 순전히 예시용입니다. 대부분의 경우 차이는 몇 퍼센트에 불과하므로 "느린" 방법을 사용하는 것이 좋습니다.
일반적으로 쉘 스크립트의 목적은 작업을 신속하게 완료하는 것입니다. 스크립트 작성에 추가 시간을 소비하는 것을 정당화하려면 최적화를 통해 상당한 이점을 얻어야 합니다.
답변2
쉘은 수신한 코드를 재구성하지 않고 단지 한 줄씩 해석할 뿐입니다(명령 해석기에서는 다른 어떤 것도 의미가 없습니다). 쉘이 소비하는 대부분의 시간은 호출하는 프로그램을 구문 분석하고 시작하는 데 소요됩니다.
간단한 작업(질문 끝에 있는 예제의 문자열 수정과 같은)의 경우 프로그램을 로드하는 데 걸리는 시간으로 인해 작은 속도 차이가 사라지지 않는다면 놀랄 것입니다.
이야기의 교훈은 정말로 더 빠른 속도가 필요하다면 Perl이나 Python과 같은 (반)컴파일 언어를 사용하는 것이 더 낫다는 것입니다. Perl이나 Python은 시작하기 더 빠르고 직접 언급된 많은 작업을 작성할 수 있습니다. 외부 프로그램을 호출할 필요가 없으며 대부분의 작업을 수행하기 위해 외부 프로그램을 호출하거나 최적화된 C(또는 기타) 모듈을 호출하도록 선택할 수 있습니다. 이것이 Fedora에서 "시스템 관리 설탕"(본질적으로 GUI)이 Python으로 작성된 이유입니다. 멋진 GUI를 추가하는 데 많은 노력이 필요하지 않으며 이러한 종류의 응용 프로그램에 충분히 빠르며 시스템 호출에 직접 액세스할 수 있습니다. . 속도가 충분히 빠르지 않다면 C++ 또는 C를 선택하세요.
하지만원하지 않는다할 수 없으면 거기로 가세요입증하다성능 향상은 유연성과 개발 시간의 손실만큼 가치가 있습니다. 쉘 스크립트는 잘 읽히지만 Ultrix를 설치하는 데 사용된 스크립트 중 일부를 해독하려고 시도할 때 몸이 떨립니다. 포기하고 너무 많은 "쉘 스크립트 최적화"를 적용했습니다.
답변3
여기서는 위의 와일드카드 예를 확장하여 쉘 스크립트 인터프리터의 일부 성능 특성을 설명하겠습니다. 30,000개의 파일 각각에 대해 프로세스가 생성되는 이 예에서
bash
및 인터프리터를 비교하면 대시 포크가 거의 빠른 속도로 처리된다는 것을 알 수 있습니다.dash
wc
bash
bash-4.2$ time dash -c 'for i in *; do wc -l "$i"; done>/dev/null'
real 0m1.238s
user 0m0.309s
sys 0m0.815s
bash-4.2$ time bash -c 'for i in *; do wc -l "$i"; done>/dev/null'
real 0m1.422s
user 0m0.349s
sys 0m0.940s
프로세스를 호출하지 않고 기본 루프 속도를 비교하면
wc
대시 루프가 거의 6배 더 빠르다는 것을 알 수 있습니다!$ time bash -c 'for i in *; do echo "$i">/dev/null; done' real 0m1.715s user 0m1.459s sys 0m0.252s $ time dash -c 'for i in *; do echo "$i">/dev/null; done' real 0m0.375s user 0m0.169s sys 0m0.203s
앞서 설명했듯이 루프는 두 셸 모두에서 여전히 상대적으로 느리므로 확장성을 위해 컴파일 중에 반복을 수행하기 위해 더 많은 기능적 기술을 사용해야 합니다.
$ time find -type f -print0 | wc -l --files0-from=- | tail -n1 30000 total real 0m0.299s user 0m0.072s sys 0m0.221s
위의 내용은 단연 가장 효율적인 솔루션이며 요점을 잘 보여줍니다. 쉘 스크립트에서 가능한 한 적은 작업을 수행하고 이를 사용하여 UNIX 시스템의 기존 논리에서 사용할 수 있는 풍부한 유틸리티 세트에 연결하는 것을 목표로 해야 합니다.
에서 도난당함일반적인 쉘 스크립트 오류저자: Padraig Brady.
답변4
내 빠른 조치:
서브셸을 사용하지 마세요.
- (서브 쉘 없음)은 (서브 쉘)
{ }
대신 자주/때때로 사용될 수 있다는 점을 명심하십시오 .( )
- (서브 쉘 없음)은 (서브 쉘)
쉘 내장 기능을 사용하면 외부 명령이 쉬워집니다.
date()
/usr/bin/date
예를 들어, 대신 쉘 함수를 호출하여 날짜를 얻으려면printf
쉘 변수를 사용하면 쉘 내장 명령이나 명령 호출이 쉬워집니다.
$SECONDS
예를 들어, 현재 시간을 얻으려면 을 호출하는 대신 쿼리를 사용할 수 있다면date()
전자가 더 빠릅니다.
문자열 조작의 경우 변수 확장을 사용하여 외부 명령 호출( 등 )
${...}
과 같은 대안을 지원합니다 .cut
tr
텍스트 파일로 작업할 때 가능하면 변수를 한 줄씩 읽는 것을 피하고 대신 전체 파일에 대해 , , 등의 외부 명령을 사용
sed
하십시오tr
.cut
- 데이터 필터링(정보 축소)을 포함하여 데이터 처리를 위해 텍스트 파일을 변수로 읽어야 하는 경우 외부 명령을 사용하여 전체 파일을 필터링한 다음 필터링된(축소된) 데이터를 변수로 읽어보세요.
정규 표현식을 사용하는 경우 역추적을 방지하기 위해 주의 깊게 작성하세요.
- 잘못 작성된 정규식의 성능은 때때로 동등한 정규식보다 100배 이상 나쁠 수 있습니다.