繁体   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