碎碎碎碎屁

从str2time开始的优化

by on 4月.07, 2013, under ,

线上有个perl的脚本,准实时(1分钟cron着)的跑着,一般一跑要1分多钟。之前初看还以为是sql设计差、脚本变量都是全局等等问题,后来想想不行,得用数据说话,于是找到了传说中的nytprof。安装据说要先装下JSON::Any,再装Devel::NYTProf;用的时候perl -d:NYTProf ./a.pl,再nytprofhtml nytprof.out下,好了现在只要w3m nytprof/index.html就能看到详细了。

不看不知道,一看吓一跳,最前面耗时最长的居然都是Date::Parse、Time::Local,而main、DBI这些原以为会慢的差前面两个Date、Time一个数量级啊。那今天就把目光放在Date::Parse里,仔细看了脚本,其实就是用到了str2time,把形如”2013-04-07 22:22:22″的转化为那个秒数。我们这个脚本大概执行一次会用到50多万次的str2time。

网上翻了翻说是Date::Parse慢,于是换了个Time::ParseDate,测试用例如下:
#1.pl
use Date::Parse;
my $start = "2013-04-08 02:00:00";
my $end = "2013-04-08 03:00:00";
for (my $i = 0; $i < 100000; $i++)
{ print str2time($start),"\n",str2time($end),"\n";}
#2.pl
use Time::ParseDate;
my $start = "2013-04-08 02:00:00";
my $end = "2013-04-08 03:00:00";
for (my $i = 0; $i < 100000; $i++)
{ print parsedate($start),"\n",parsedate($end),"\n";}

time比较出来的时间是从原来的13秒变成9秒,稍有提高。

期间多次strace发现经常会访问/etc/localtime,怀疑是模块里不论何时都要去算下现在时间引起的,遂决定直接用timelocal这个最基本的命令传入年月日时分秒来计算。
#3.pl
use Time::Local;
sub new() {
$_ = @_[0];
my( $Y,$M,$D,$h,$m,$s ) = /(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})/;
return timelocal($s,$m,$h,$D,$M-1,$Y);
}
my $start = "2013-04-08 02:00:00";
my $end = "2013-04-08 03:00:00";
for (my $i = 0; $i < 100000; $i++)
{ print &new($start),"\n",&new($end),"\n";}

于2.pl的耗时比较,从9秒降到6秒多。

strace里还是能看到访问/etc/localtime,在Time::Local里看到还有timegm,试试
> return timelocal($s,$m,$h,$D,$M-1,$Y);
< return timegm($s,$m,$h,$D,$M-1,$Y)-28800;

由于并不牵涉时区,遂直接写死在里面。瞬间,从6秒多降到2秒内,和最开始比已经下降了一个数量级了。所以那,调用次数高的函数啊一定要好好调教下~

把这个提给原脚本owner后发现,原脚本只是为了比较两个时间string转后的大小。他直接改成
> return timegm($s,$m,$h,$D,$M-1,$Y)-28800;
< return ($Y*366*24*3600 + $M*31*24*3600 + $D*24*3600 + $h*3600 + $m*60 + $s);

来进行比较。时间差不多从2秒内变为1秒内。

然后洗澡时候忽然想起别人说过笑话,数据库存时间直接用string存20130407222222,于是测试这样比大小。
sub new() {
$a = @_[0];
$a =~ tr/ \-://d ;
return $a;
}
my $start = "2013-04-08 02:00:00";
my $end = "2013-04-08 03:00:00";
for (my $i = 0; $i < 1000000; $i++)
{ if (&new($start) < &new($end)){print 1};}

测试用例上提高一个数量级跑,上一种7秒多,这一种2秒多。
#p.s.用=~ s/\-|\s*|\://g;代替=~ tr/ \-://d;会比上一段所说的还要慢
也就是说,最开始13秒的,现在已经变成0.2秒了,所以那,优化逻辑也很重要~

改了之后load下降

Leave a Comment :, more...

密码保护:2012总结

by on 1月.03, 2013, under review

这是一篇受密码保护的文章,您需要提供访问密码:

要查看留言请输入您的密码。 more...

密码保护:2012上半年

by on 7月.02, 2012, under review

这是一篇受密码保护的文章,您需要提供访问密码:

要查看留言请输入您的密码。 more...

毕业了

by on 6月.15, 2012, under review

毕业了,拿到了工学学士学位,俗称B.Eng.

接着要开始恶俗的回顾历史了唉。

高考考完报学校,抱着打死不出杭州的思想,观摩了下沙几所大学,最后还是选择浙江工业大学。而专业“食品科学与工程”也是我第一选择专业。

p.s.N多人问我为嘛不选计算机,理由如下:1.被逼着看电脑屏幕太累 2.男女比例太不和谐 3.学的好多东西已经过时

而在高考结束的那个暑假(2008年),差不多把所有想玩的都玩掉了,驾照到手,炒股上手,好了,蛋定的入学。

现在看起来入学之后最有意义的就是加入了“精弘网络”,一个现在算是校级的学生组织,大一在里面做平凡苦力,大一下过了技术考之后转技术。凭借在其学到的技术以及实践,在大三上进入淘宝实习,大四上的年底过了转正考,在10天之后即将正式入职淘宝网。

大一真的叫懵懂,几乎不跷课,尤其是大一上(2008秋),连晨练打卡都按时去,虽然和梦游一样打完卡吃完早饭继续睡觉。想来大一的睡眠真是极其充分,23点睡算迟的了,如果上午没课11点起算早的了,还要定个闹钟怕下午课也睡过。而在大一下(2009春),做了假章之后晨练打卡也无视了,睡的更安稳了。大一开始不能带电脑,大一下的3月悄悄带电脑后发现寝室上不来网(新造的宿舍楼全楼没接入),等到能上网的时候做了假学生证复印件开了帐号,回寝室开代理给寝室里也带电脑的人一起上网。大一的体育课也是有意思的,野外拓展,差不多就是玩游戏,最后一次课是绳降。大一的第一次出游是清明跟着同寝的回他爷爷家,无锡、苏州;接着5月舟山、普陀、宁波,蹭在舟山的高中同学的寝室;在6月期末考之后还去了绍兴,蹭同学家。这三次出游都没有住宿问题。

大一暑假(2009夏),开头是军训大半个月,之后就是日全食啦、各种觅食啦、聚会啦、买域名搭博客啦,还有和高中同学总共6人去了西塘。最后就是准备两门考试,一是大一下学期高数挂了的补考,补考以90分的成绩过了,而且在最终成绩单上也是90分,算是有分数的科目里最高的一门;二是国家计算机三级网络技术,现在看来也是没用的考试。

大二(2009秋)在朝晖校区,撤离了美丽的小河山,离家好近了…10月份去了厦门,回来时候两人口袋都只剩¥50。大二上挂了有机,补考70分。大二寒假(2010春)开始vps,大二下班级春游去南京,想念早起吃的蒋有记,4月份跟着去了福建土楼,顺带又厦门呆了一天。大二下挂了物化,补考80分。

大二暑假(2010夏)暑期实践,四川,坐(硬座)了34小时火车到成都,再5小时坐到广元,反正实践内容很水,主要是玩,九寨、黄龙、西安,总共18天漂泊在外,爽。

大三上(2010秋)去淘宝校招求了个实习回来,考了个公共营养师(高级)。

大三下(2011春),由于空的时候都去实习,所以都没啥工夫玩,4月去了镇江、扬州。大二上下两学期是体育课的游泳课,大三上选了公选课的游泳课,大三下厚着脸蹭了一学期的公选课游泳课。5月去了湖南,6月看了次日出。

大三暑假(2011夏)正儿八经的实习,8月跟着小学同学去了趟新加坡,蹭住的就是好。

大四上(2011秋)确定了毕业课题——松木层孔菌多糖提取和体外活性研究,最后拿了个良。申请到4sq superuser,似乎杭州就我一个,现在升级到level2。12月实习转正。

大四寒假(2012初)部门里过年期间人手不够,毕业实验做了一开头又被拉去实习,到2月下半月回学校做实验,做实验做了n久,差不多一直到5月中。1月收了人生第一张罚单。

大四下(2012上)毕业气氛一直在回荡,粗翻日记就是各种聚餐,通宵啊夜游啊不计其数(sum<10)。5月在赶论文,所以有点麻木,反正不是玩就是吃,期间有72小时5顿聚餐的记录。而6月整个就是伤感月,从2002年小学毕业第一次体会,我就知道每年的6月都是伤感的。写出来伤神,看起来伤心。

最后的最后相册们

3 Comments :, , , more...

$PS1增加py的virtualenv支持

by on 4月.09, 2012, under ,

刚刚开始学用python的virtualenv,顺带用上了virtualenv wrapper,发现默认会在PS1之前加上($VIRTUAL_ENV),不好看啊,和我原来的不匹配。然后就花了几小时去改之前就写的很头大的PS1。现在显示到右边啦~

新版PS1效果图

PS1='${debian_chroot:+($debian_chroot)}`a=$?;if [ $a -ne 0 ]; then a=" "$a; echo -ne "\[\e[s\e[1A\e[$((COLUMNS-2))G\e[32m\e[1;41m${a:(-3)}\e[u\]\[\e[0m\e[2m\]"; fi`\[\033[01;32m\]\u@\[\033[01;35m\]\h\[\033[00m\]:\[\033[01;34m\]`pwd`\[\033[00m\]`B=$(git branch 2>/dev/null | sed -e "/^ /d" -e "s/* \(.*\)/\1/"); if [ "$B" != "" ]; then S="git"; elif [ -e .bzr ]; then S=bzr; elif [ -e .hg ]; then S="hg";B="$(hg branch)"; elif [ -e .svn ]; then S="svn"; else S=""; fi; W="\`showvirtualenv 2>/dev/null \`"; if [ "$W" != "" ]; then if [ "${W:0:14}" = "showvirtualenv" ]; then W=""; else W="workon:$W"; fi; fi; if [ "$S" != "" ]; then if [ "$B" != "" ]; then M=$S:$B; else M=$S; fi; fi; if [ "$W" != "" ]; then if [ "$M" = "" ]; then M=$W; else M="$W $M"; fi; fi; [[ "$M" != "" ]] && echo -en "\e[s\e[$((COLUMNS-${#M}-1))G\e[33m\e[1;40m($M)\e[0m\e[u"`\n\[\033[01;34m\]\$\[\033[00m\] '
不分割了,太损血了。

Leave a Comment :, , , more...

Page 3 of 121234510...last »