中国IT动力,最新最全的IT技术教程
最新100篇 | 推荐100篇 | 专题100篇 | 排行榜 | 搜索 | 在线API文档 | 网通镜像
首 页 | 程序开发 | 操作系统 | 软件应用 | 图形图象 | 网络应用 | 精文荟萃 | 教育认证 | 硬件维护 | 未整理篇 | 站长教程
ASP JS PHP工程 ASP.NET 网站建设 UML J2EESUN .NET VC VB VFP 网络维护 数据库 DB2 SQL2000 Oracle Mysql
服务器 Win2000 Office C DreamWeaver FireWorks Flash PhotoShop 上网宝典 CorelDraw 协议大全 网络安全 微软认证
硬件维护  CPU  主板  硬盘  内存  显卡  显示器  键盘鼠标  声卡音箱  打印机  机箱电源  BIOS  网卡  C#  Java  Delphi  vs.net2005
  当前位置:> 程序开发 > 编程语言 > 综合其它
一个Shell程序的性能优化(2)
作者:佚名 时间:2007-09-24 16:33 出处:中国IT实验室 责编:月夜寒箫
              摘要:一个Shell程序的性能优化(2)

将以上程序投入运行,号段文件有71行记录,需要分拣的通话话单文件17万条左右通过观察发现此方法的执行效率确实比解决方法1提高了很多,但是仍需要数小时的时间才能执行完毕。我另外写了一个同样功能的C语言程序,执行同样的测试数据得出结果仅需要10~15秒的时间!shell程序确实要比同样功能的C程序慢一些,但是目前的情况是用C程序处理只需要几秒钟时间,而Shell程序确需要数小时!在用此Shell程序处理的时候我用Top命令看了一些系统资源的消耗发现CPU、内存以及IO的占用都极小,说明系统资源很充足,不是系统的问题造成了程序处理速度慢。问题出在哪了呢?

我用命名ps-ef观察系统进程的运行情况,发现每过几秒种就会有一个expr进程产生,这个进程运行很短的时间就消失了(不仔细观察可能都看不到有expr这个进程产生)。这时候我觉得我好像发现程序运行慢的原因了:程序的几个循环里面都有用expr进行计算的语句,expr属于Shell外部命令,所以每次运算都要产生一个expr进程,而程序的运行种最消耗时间的除了IO操作外就数产生新进程操作了,于是我决定把用expr进行计算的地方都尽量修改为用shell的内部命令进行计算。程序变成了下面的样子(标注1~标注6为修改过的地方):

程序代码如下:

            

#!/bin/bash

#Author Xsh  date:08-15-2006

echo "Time:$(date)==>Strat to processing........." #显示程序开始运行时间

while read numseg

 do

  tmplow="${tmplow} $(expr substr ${numseg} 1 10 & >/dev/null ) "

  tmptop="${tmptop} $(expr substr ${numseg} 12 10 & >/dev/null ) "

done < ./numseg.txt #循环读取号段文件下限号段存入变量tmplow,上限号段存入变量tmptop

arr_lownug=(${tmplow}) #将下限号段存入数组arr_lownug

arr_topnug=(${tmptop}) #将上限号段存入数组arr_topnug

#定义函数checknum(),输入参数为需要检查的"计费号码",输出参数为0或者1

#函数checknum()输出为0 表示"计费号码" 不在号段文件的所有号段范围内

#函数checknum()输出为1 表示"计费号码" 在号段文件的所有号段范围内

#函数checknum()中用二分搜索法进行号码的判断

checknum(){ #函数定义开始

thisnum=$1

ckresult=0

lowflag=0

topflag=$((${#arr_lownug[*]} - 1 ))   #标注1

MaxIndex=$((${#arr_topnug[*]} - 1 ))  #标注2

midflag=0

midflag=$((${topflag} / 2 ))       #标注3

if [ "${thisnum}" \< "${arr_lownug[0]}" -o "${thisnum}" \> "${arr_topnug[${MaxIndex}]}" ]

then

return 0

else

while [ "$lowflag" != "$midflag" ]

do

if ["$thisnum"\> "${arr_lownug[${midflag}]}" -o "$thisnum" == \

"${arr_lownug[${midflag}]}"]

then

lowflag=${midflag}

midflag=$(( $((${topflag} + ${lowflag})) / 2 )) #标注4

elif["$thisnum"\<"${arr_lownug[${midflag}]}" -o "$thisnum" == \

"${arr_lownug[${midflag}]}"]

then   

topflag=${midflag}

midflag=$(($((${topflag} + ${lowflag})) / 2 )) #标注5

else

echo "Error!"  

fi

done

if ["$thisnum" \< "${arr_topnug[${lowflag}]}" -o "$thisnum" == \

"${arr_topnug[${lowflag}]}"]

then

return 1

else

return 0

fi

fi

}#函数定义结束

while read f

do

org="${f:0:10}"  #标注6

checknum ${org}

returnval=$?

if [ "$returnval" == "1"  ]

then

echo "${f}" >> ./Match_result.cdr  #将匹配的记录存入结果文件1

else

echo "${f}" >> ./NoMatch_result.cdr #将不匹配的记录存入结果文件2

fi

done < ./rttest.txt

echo "Time:$(date) ==> Proccess is end! "

exit 0;

将修改过的程序进行运行,很快就得出了结果,总的运行时间没有超过8分钟。此时这个程序的运行效率已经基本可以让人接受了。同样的一个问题由于改进了程序算法和充分利用了LinuxShell的内置运算符,将程序的运行时间大大的缩短。当然此程序还有可以改进的地方,对此文感兴趣的读者可以对此程序做进一步优化。

关闭本页
 
首页 | 投资与合作 | 服务条款 | 隐私政策 | 收藏本站 | 设为首页 | 新用户注册 | 免责声明 | 使用帮助
Copyright ©2005-2008 chinaitpower.com All rights reserved. www.chinaitpower.com 版权所有