Bash 스크립트 성능

Bash 스크립트 성능

스크립트 에서는 bash범위의 일부 정수가 생성되고 고정 문자열과 연결되어 파일에 인쇄됩니다. 운영체제는 Ubuntu 14.04이고 bash버전은 4.3.11(1)-release.

인쇄할 문자열(및 줄)이 수백만 개 있습니다. 다음은 iotop하드 드라이브 사용 횟수입니다.

 TID  PRIO  USER     DISK READ  DISK WRITE  SWAPIN     IO>    COMMAND  
5701 be/4 myuser    408.24 B/s   97.27 K/s  0.00 %  0.23 % bash ./script.sh
5701 be/4 myuser    408.20 B/s   97.27 K/s  0.00 %  0.00 % bash ./script.sh
5701 be/4 myuser    408.41 B/s   95.72 K/s  0.00 %  0.11 % bash ./script.sh

100만 개의 문자열을 인쇄하는 데 약 16분이 소요됩니다. 하드 드라이브의 대역폭은 포화 상태와는 거리가 멀습니다. uptime15분 이상 실행한 후:

load average: 0,97, 1,14, 1,19

4코어 CPU에서. 따라서 CPU나 하드 드라이브 모두 극도로 느린 실행의 원인은 아닌 것 같습니다.

  1. 이 프로세스를 어떻게 가속화할 수 있습니까?

  2. 이것이 여전히 가능합니까 bash, 아니면 다른 언어를 사용해야 합니까?


스크립트의 관련 부분은 다음과 같습니다.

#!/bin/bash

i=0
a='fixedstring1'
b='fixedstring2'

while [[ $i -le 9999999 ]]; do
[...]
    ur="$a""$b""$i"
[...]
    echo $ur >> exp1/file$m
[...]
    (( i++ ))
done

file$m생성된 첫 번째 파일 입니다 m. 스크립트는 모든 줄이 포함된 고유한 파일이 아니라 고정된 수의 줄이 포함된 여러 파일을 생성합니다.

답변1

귀하의 경우 Bash 루프는 매우 느립니다.

> cat test-1.sh
#!/bin/sh

i=0
a='fixedstring1'
b='fixedstring2'


while [ $i -lt ${1:-9} ]; do
  ur="$a""$b""$i"
  echo $ur
  (( i++ ))
done

> time sh test-1.sh 999999 | wc -l
...
real    1m11.488s

jot(또는 )을 사용하면 seq속도가 빨라집니다.

> cat test-3.sh
#!/bin/sh

a='fixedstring1'
b='fixedstring2'

jot -w "$a$b" ${1:-9}
# seq -f "$a$b%g" ${1:-9}
> time sh test-3.sh 999999 | wc -l
...
real    0m0.613s

그리고 디지털 아카이브를 분할하는 논리는 무엇입니까? 단순히 줄 수를 제한하려면 split다음 명령을 사용할 수 있습니다(이제는 옵션 GNU split사용을 의미합니다 -d).

sh test-3.sh | split -d -l "how much lines in one file" - expr1/file

답변2

동일한 파일을 반복적으로(아마도 수백 번) 열고 닫습니다. 각 파일을 최대 한 번 열어 보십시오.

i=0
a='fixedstring1'
b='fixedstring2'
m=0

exec 3>exp1/file$m

while [[ $i -le 9999999 ]]; do
    ur="$a$b$i"
    if ... # m changes
    then
        exec 3>exp1/file$m
    fi
    echo $ur >&3
    (( i++ ))
done

이는 루프 내에서 특정 명령을 리디렉션하는 대신 전체 루프를 리디렉션하는 것과 동일한 조언입니다.

관련 정보