[英]Improving performance of comparing file column to array in bash
我正在將一系列文件中的行與 bash 中的浮點數組進行比較。 簡而言之,有問題的文件(../summarize_eigenvectors/"$xct"_ / -5_1-sorted.txt)具有以下結構
c v weight ik kx ky kz
1 1 0.00000 1 0.00000 0.00000 0.00000
1 1 0.00000 2 0.00000 0.04167 0.00000
1 1 0.00000 3 0.00000 0.08333 0.00000
並且該數組是從../vici_absdipole_noeh/v1c5.data 生成的,其格式如下:
kx ky kz ik ic iv is ec (eV) ev (eV) eig (eV) abs(dipole)^2 Re(dipole) Im(dipole)
0.00000 0.00044 0.00000 1 1 1 1 0.11713703E+01 -0.12426462E+01 0.24140165E+01 0.69913425E-04 0.81359347E-02 0.19287282E-02
0.00000 0.01883 0.00000 2 1 1 1 0.11760590E+01 -0.12490846E+01 0.24251436E+01 0.59405512E-04 -0.70114501E-03 0.76755396E-02
0.00000 0.03722 0.00000 3 1 1 1 0.11746489E+01 -0.12612625E+01 0.24359113E+01 0.37648401E-04 -0.46637404E-02 0.39872204E-02
0.00000 0.05561 0.00000 4 1 1 1 0.11868220E+01 -0.12787400E+01 0.24655620E+01 0.18552618E-04 -0.21585915E-02 0.37273450E-02
我的代碼所做的是將文件 v1c5.da 的第 4 列中的整數與我的數組進行比較; 如果對於文件的一行,第 4 列元素在“列表”數組中,則該行中的文件索引、權重、ik、kx 和 ky 的值被回顯。
這是我的工作代碼示例,它將 7485 個文件(每個文件有 1152 行)與 1152 個元素的數組進行比較
#!/bin/bash
#generates the array from information given in another file
for i in range $(seq 2 1153)
do
ik=$(awk -v i=$i 'NR==i''{ print$4 }' ../vici_absdipole_noeh/v1c5.data)
dp2=$(awk -v i=$i 'NR==i''{ print$11 }' ../vici_absdipole_noeh/v1c5.data)
dp2f=$(printf "%.8f" $dp2)
if (( $(echo "$dp2f > 6" |bc -l) )); then
list+=("$ik" )
fi
done
echo "xct ik weight kx ky" > v1c5-high_dp2_kpts.txt
task(){
echo working on $xct
for line in {1..1152};do
weight=$(awk -v line=$line 'NR==line''{ print$3 }' ../summarize_eigenvectors/"$xct"_*/*-5_1-sorted.txt)
ik=$(awk -v line=$line 'NR==line''{ print$4 }' ../summarize_eigenvectors/"$xct"_*/*-5_1-sorted.txt)
kx=$(awk -v line=$line 'NR==line''{ print$5 }' ../summarize_eigenvectors/"$xct"_*/*-5_1-sorted.txt)
ky=$(awk -v line=$line 'NR==line''{ print$6 }' ../summarize_eigenvectors/"$xct"_*/*-5_1-sorted.txt)
if [[ " ${list[@]} " =~ " ${ik} " ]]; then
echo "$xct $ik $weight $kx $ky" >> v1c5-high_dp2_kpts.txt
fi
done
}
for xct in {1..7485};do
((i=i%360)); ((i++==0)) && wait
task "$xct" &
done
wait
該代碼已經運行了 8 個小時以上,並且只處理了 1700 個文件,這相當慢。 此代碼中是否存在限制其性能的瓶頸? 如果有,我該如何改進它?
我在每個節點有 24 個內核的高性能計算中心節點上運行它,因此我也使用了並行化來加快速度。 顯然這還不夠。
您的task
function 確實效率低下。 它每次循環重讀所有文件4次,只處理一行。 您可以在一次awk
調用中完成所有工作。
task(){
echo working on $xct
cat ../summarize_eigenvectors/"$xct"_*/*-5_1-sorted.txt |
awk -v list="${list[*]}" -v xct="$xct" '
BEGIN {
split(list, list_array); # split string list into array list_array at whitespace delimiters
for (i in list_array) list_hash[list_array[i]] = 1 # associative array with $list elements as keys
}
{
weight=$3; ik=$4; kx=$5; ky=$6;
if (ik in list_hash) printf("%s %s %s %s %s\n", xct, ik, weight, kx, ky)
}' >> v1c5-high_dp2_kpts.txt
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.