arrays - 提高 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
功能确实效率低下。它每次循环重读所有文件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
}
推荐阅读
- exchangewebservices - 终止对 Exchange Online 中的基本身份验证的支持以及为即将停用的 Web 应用程序降级组织安全性的方法
- html - 主 div 和页脚之间的空白
- python - Bio.Alphabet _verify_alphabet 函数现在位于哪里?
- windows - 高对比度隐藏菜单项文本
- mysql - 如何使用 INNER JOIN 进行选择,给出相关但不相关的记录
- cognitoforms - Cognito 表单预填充失败
- sql - 为什么表变量 SQL 不返回 R Markdown 中的值?
- git - CephFs 和 CephRBD 对 git clone 的速度很慢
- flutter - 为什么控制台中没有显示错误?
- jquery - 当页面在 Laravel 上重新加载时如何保留选定的表