배열에서 가장 높은 값(350 int 값)을 찾으려면 max 함수가 필요했고 재귀의 친구로서 재귀 접근 방식을 시도했습니다.
max () {
len=$#
a=$1
b=$2
case $len in
0)
echo NaN
;;
1)
echo $1
;;
2)
(( a > b )) && echo $a || echo $b
;;
*)
shift; shift
max $(max $a $b) $(max $@)
;;
esac
}
놀라울 정도로 느립니다. 350개의 값은 2.6초가 소요됩니다.
예, 정식 유닉스 방식은 다음과 같습니다.
time (echo ${yvals[@]} | tr " " "\n" | sort -n | tail -n 1 )
0,005초와 while 루프가 소요됩니다.
max () {
anz=$#
max=$1
while ((anz > 0))
do
b=$2
(( b > max )) && max=$b
shift
anz=$#
done
echo $max
}
0,010초와 크게 다르지 않습니다. 두 배 느린 속도이지만 값이 너무 낮으면 오차 범위가 측정된 값보다 높을 수 있습니다. 값 개수가 너무 높지 않은 한 가장 빠른 성능에는 별로 관심이 없습니다. 하지만 gnu-parallel이 개선을 가져올 수 있을지 궁금해서 오랫동안 병렬성에 대해 더 많이 배울 수 있는 기회를 기다려왔지만 실제 사례를 통해 배우는 것을 선호하고 사례가 거의 없습니다. , 이는 병렬화의 이점을 누릴 수 있습니다.
그래서 나의 순진한 접근 방식은 재귀 버전을 시도하는 것이었습니다.
time parallel max ::: ${yvals[@]}
그리고 -j+0과 같은 몇 가지 병렬 실험 옵션을 추가했습니다. 이 옵션은 350개의 값을 생성하며 각 값은 다른 값과 비교되지 않으므로 그 자체가 최대값입니다. :)
맨페이지를 참조한 것 외에도 Ole Tange의 YT 동영상 4개 중 2개도 시청했습니다.GNU 병렬, 약간의 수정을 거쳐 채택할 수 있을 만큼 내 사용 사례에 가까운 예제를 찾았지만 아무 것도 찾지 못했습니다.
그래서 SE에게 물어볼 생각이 있었지만 다른 일로 주의가 산만해지고 6개의 셸 창 기록이 엉망이 되어 질문을 쓰기 시작했고 명령을 기록하고 싶었습니다. 시도했지만 지금은 다음과 같이 썼습니다.
time parallel -X max ::: ${yvals[@]}
6933
1689
23676
31553
놀랍게도 실제로 작동합니다. 예, 코어가 4개이므로 4개의 결과가 있으며 어느 것이 가장 큰지 쉽게 파악할 수 있습니다. 이러한 최대값 중 최대값을 취하는 max 함수를 작성할 수 있습니다.
time max $(parallel -X max ::: ${yvals[@]})
31553
real 0m0,501s (Only a 5th of the time, used without parallel).
따라서 0.5초는 셸에서 대화식으로 작업하는 데 허용되는 범위이지만, 물론 이 경험을 달성하는 것은 단지 행운과 적절한 레코드 수일 뿐입니다. 쉘이 재귀 성능이 좋지 않은 것으로 알려져 있습니까? 이것은 내 주요 문제가 아닙니다.
주요 질문은 결과에 대해 함수를 다시 실행하는 정식 병렬 방법이 있는지 여부입니다. 이는 함수형 프로그래밍의 문제를 해결하는 일반적인 방법입니다.겹. 지도/감소는 원칙적으로 동일하다고 생각합니다.
대부분의 경우 내가 다루는 데이터가 작기 때문에 병렬 처리에 들어가고 나가는 방법을 배울 기회와 고통이 부족합니다.
답변1
max
Bash의 처음 500개 값에 대해 함수는 O(n^2) 시간에 실행됩니다. 이는 max
잔존 가치로 통화를 했기 때문일 가능성이 높습니다 . 따라서 이 값을 복사해야 합니다.
mmax() {
max $(seq $1)
}
seq 10000 | env_parallel --joblog bash.log mmax
(echo '#Bash';echo '#JobRuntime in seconds';field 10,4 < bash.log |sort -n) |
head -n 1000 | plotpipe
처음 1000개 값의 경우 상황이 약간 혼란스럽습니다.
ksh
처음 500개 값 에 대해서는 명확하지 않습니다.
그러나 1000개의 값에 대해서는 O(n^2)처럼 보입니다.
ksh
12:37에 충돌 발생:
( plotpipe
그리고 field
다음에서:https://gitlab.com/ole.tange/tangetools).