簡體   English   中英

提高 bash 中文件列與數組比較的性能

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM