分类: tech

  • 如何使用google的cpplint.py

    http://code.google.com/p/google-styleguide/ 这是google使用的一个C++代码风格规范,可以作为平常开发的参考。

    作为风格参考,google还推出了一个cpplint.py的脚本,可以用作风格规范检查使用。可以在这里下载

    http://google-styleguide.googlecode.com/svn/trunk/cpplint

    在windows下的使用方法也非常简单,(安装python后)把cpplint.py放在项目目录下,然后进入命令行,敲打命令如下:

    C:\temp\>cpplint.py –output=vs7 test1.cpp

    可以通过cpplint.py –help来查看帮助。注意,命令行参数都是两个横线(–)。

  • strlen与性能问题

    在Tony bai的博客上看到他提起strlen的性能问题,这还真是比较有意思的一个话题。

    我在前一阵专门用两周时间来对代码做优化,问题的起因是我们组有人提出来程序跑的慢,另外使用接口功能的外国同事也提起过几次。关于优化还专门做了一张ppt演示,有空节选一下分享出来。不过有意思的是,最后发现速度的最大瓶颈其实并不是在我们新加了多少功能,而是两方的客户端调用代码都写的太烂了,这种巧合都能碰到一起,太奇妙了。

    印象中BSD的kernal开发人员delphij也曾经提到过strlen,开起google一搜果然如此。strlen这个函数貌似简单容易写,但是里面的花花肠还真不少呢。这也间接的说明了阅读学习经典代码的重要性。

  • 一些google开源的项目介绍

    编程中,经常会用到一些开源库或者项目,比如c++中经常用到的boost。

    google的主要软件架构基于linux,c,c++,java,而且作为一个创新型的公司,他们也经常性的回馈社区一些优秀的代码。在不断的反馈修改中,代码质量得到了提高,用户得到优质服务,这也算是双赢的结果。而且google里面牛人多,写出来的代码质量相对比较高,有很大的学习价值。

    周末无事,搜索code.google.com/p,找到一些有趣的google参与的项目,在这里简单分享一下。有一些开源项目没有列出来,主要因为平台是linux-only或者对项目本身不感兴趣。如果想找完全列表,可以在这里看到:
    http://code.google.com/hosting/projects.html

    另外也可以使用google这个label来搜索code.google.com/p,但是这样也许搜出来的并不一定是google开发的项目。

    ———————————-

    http://code.google.com/p/omaha/

    这是最新放出来的google update的代码,想做windows在线update功能的可以参考。(c++)

    http://code.google.com/p/google-breakpad

    http://code.google.com/p/google-glog/

    breakpad,一个项目的开始需要做一些什么样的基础设施,crash dump和运行logging毫无疑问都是应该有的,这个项目就是负责在crash的时候收集信息,发出crash dump报告的。(c++)

    glog就是用于项目中logging功能的,一般桌面程序不太需要logging,但是对于大规模长时间服务的系统来说,logging功能一定要有,而且要记录足够多的信息。(c++)

    http://code.google.com/p/protobuf/

    protocol buffer,可以用来在跨进程、跨机器,不同操作系统,不同编程语言之间进行数据交换。类似于微软的COM IDL或者XML,但是解析速度更快,需要传输字节数更少。(c++, java, python)

    http://code.google.com/p/chromium/

    google chrome浏览器项目,基于webkit,想自己开发个浏览器,学习这个吧。(c++)

    http://code.google.com/p/google-perftools/

    TCMalloc,heap检测,是一个google用于性能检测的工具。(c++)

    http://code.google.com/p/jaikuengine/

    jaiku是被google收购的微博客服务,类似twitter,但是google买下了以后没有什么动作。在将jaiku移植到appengine平台以后就做出了开源而且不再继续开发的决定,jaiku也就这样了。当然,幸福的还是我们这些程序员。(python)

    http://code.google.com/p/googleappengine/

    这个只是appengine在桌面进行测试运行的项目,相比google服务器上的appengine,肯定还是有着相当大的区别。不过我们也可以从中学到google对于python的使用,不是么?(python)

    http://code.google.com/p/v8/

    google chrome浏览器中的javascript引擎项目。可以单独用作解析javascript,号称速度非常快。(c++)

    http://code.google.com/p/app-engine-site-creator/

    使用appengine建立企业及个人网站的朋友,可以试试这个项目。(python)

    http://code.google.com/p/googlemock/

    http://code.google.com/p/googletest/

    测试框架组合,mock怎么用实话说我也不清楚。

    http://code.google.com/p/google-styleguide/

    google c++编码规范,可以学习学习,网上有中文版的了。

    http://code.google.com/p/google-email-uploader

    outlook邮件上传到gmail,可以学学c#。

  • 开发者必读博客Top100-2009年第一季版本

    http://www.noop.nl/2009/03/top-100-blogs-for-developers-q1-2009.html

    这个博客是我前一阵发现的,其中有篇文字100个软件面试问题还在最近一期的《程序员》杂志被人(不是我)翻译出来。

    这个主题,noop.nl在以前写过,但是已经有些过时了,那只是08年底啊。可以想见软件开发这个领域的后浪推前浪真是太猛了。

    懂英文的朋友,还是建议大家去看原文,里面有很多搞笑的文字,我也不全文翻译了。

    2009年Q1版本的变化主要是删掉了一些不更新的博客以及讨论主题不是软件开发的,仅专注某个开发语言(如ruby)的也被删掉,整个top100是基于google rank,alexa rank,twitter follow人数以及博客留言人数来作为评定基准的,收录的博客也都是讨论通用软件开发领域的。

    下面就是软件开发top100博客列表,前面是博客地址,后面是博客作者的twitter地址。第一个数字是本场名词,后面的LT是上次评比名词。权威不权威暂且不论,可以作为一个选择博客、扩大阅读知识面的参考。

    TT LT Blog / Site Author / Twitter

    1 1 Joel on Software Joel Spolsky

    祖尔谈软件依然是第一名,从文章质量来说,真是当之无愧,而且应该注意的是,不知是否是Noop.nl的一个故意所为,实际上后面第十名的stackoverflow也应该是Joel参与的一个网站。

    2 3 Coding Horror Jeff Atwood

    Coding horror最近一个介绍Peer review编程的文章很有意思,里面提到英雄也是有伙伴的,比如蝙蝠侠和罗宾,列侬与麦卡特尼,马里奥与路易等等。

    3 6 Martin Fowler’s Bliki Martin Fowler

    不用说了,看到Martin,就冒出敏捷啊、重构啊、模式啊,都是时髦词。

    4 11 The Daily WTF (various)

    WTF,是英文Worse than Failure的缩写,但是估计大家都会把它看成What the fuck。在博客的about里提到算是一个幽默型的博客,可惜对于西方人的幽默,有的不是很理解。

    5 67 Signal vs. Noise (various)

    信号vs噪声,看上去像是搞电子的啊,实际是37signals的一个博客,主题是设计、商业、经验等等。ROR的家,页面设计感觉很舒服。

    6 5 Scott Hanselman’s Computer Zen Scott Hanselman

    这个博客关注的是微软开发技术,从他的tags里就能看出来,有关注微软DotNet、Asp.net,可以去看看。

    7 10 Rands in Repose Michael Lopp

    这个博客的主题应该是管理,最新一篇文字Tweet的艺术很好玩。里面提到Say more with less(文字要精炼)以及Don’t Say What You’re Doing, Say Why You’re Doing It(不要说你正在做什么,而是说你为何做这个)

    8 7 Bokardo: Social Design Joshua Porter

    博客主题是社会性设计,里面谈论的是facebook、digg这样的社会性软件。我个人不是很感兴趣。

    9 8 Stevey’s Blog Rants Steve Yegge

    看不太出来主题,应该是动态语言、设计方面

    10 19 Stack Overflow Jeff Atwood

    近期很火爆的程序设计方面问答社区。

    后面的列表就不详述了,大家有兴趣的,可以一个个慢慢看,可以直接导入这个opml文件阅读整个top100列表。

  • 程序优化经验谈

    项目接近尾声,我们开始做各种各样复杂一些的测试,优化在这个时候成为一个比较明显的问题。

    也许有的朋友会说,为何一开始不考虑优化?作为一个老程序员,基本的一些常识还是有的,比如不去反复调用一些初始化操作,GetCount或者是GetSize这样的操作不放在循环里面进行,但是运行性能问题还是会发生。在最后的时候优化,算是一个比较好的时机,因为过早优化会没有目的性,既然客户端没有进行实际的调用,怎么知道那些操作会带来性能问题呢,只有跑起来才知道。

    我们项目是一个组件程序,通过COM接口被其他程序使用,设计为了简单,将一些数据放在注册表里存放,另外其他大部分数据都是读取一个格式化的文本文件(EDS)来获得的。程序的整个结构是单线程的,同一个进程中,任何一个复杂操作都会阻塞其它调用的进行。

    代码优化的重点是放在初始化这个阶段,因为我们需要读文件来构造整个系统,这其中牵扯到注册表操作以及文件操作和对文件解析生成特定的实例(instance)。

    注册表的优缺点暂不评论,但是它的性能真的是很成问题,注册表是典型的key-value结构,按理说读取速度应该很快,但是它真的很牵扯性能,这个地方的优化做了一些,但是本质上没办法做更多的优化,个人倒是比较喜欢一些简单的数据库作为程序后端存储,比如很多公司都用到的sqlite引擎,支持sql语言查询,性能还算是不错,应该可以作为一个很好的替代品。问题是类似东西可能有license引用的问题,这个就比较复杂了。

    我们组里另外一个同事针对注册表操作做了一些改进,估计这方面也不能做的更好了。所以注册表方面暂借不管,主要精力放在内部代码改进。

    首先必须要做的就是收集数据,看看那些函数调用费时间。好在我已经有现成的log以及高性能计时器类,只要包含一下就可以。有的朋友会说log文件有多线程问题,计时器有多cpu问题。没错,但是我们程序是单线程的(见前面说明),所以写文件时候不加锁,另外尽量只建立一个全局log实例,保证创建、关闭文件操作非常少,而且也不进行内存new/delete操作。为何不使用OutputDebugString?好问题,这个函数可能导致一些时序上的问题(可以搜索codeproject上面有介绍文字),可以用,但是不如写文件那么simple。感觉这些也许是问题,但是还是尽量简化这些工具,够用就好。

    经过性能数据收集,发现读取、解析文件使用时间不多,相比来说将数据序列化类实例比较耗时,因为我们加入了很多验证的函数调用,导致新的代码比前一个版本需要更多的调用。当然可以去掉这些验证,但是那我们还做这个新版本干嘛呢。

    根据现在得到的数据,主要下面一些改进:一个是将一些集合类加入对map的继承关系,相当于重新又包装了一次抽象。原因是我们在查询这些集合类的时候都是使用的循环for-loop调用,相比map的查询,就差了不少。(学过数据结构的朋友应该了解stl的map查询性能要好很多,因为内部一般是用树状结构实现的)。另外一个改动就是把一些不必要的初始化操作放在后面进行,这样就导致我们需要在一些函数调用时加上它相关的初始化调用,代码复杂了不少,但是也没有办法。还有一个常用的手法就是使用cache,把一些运算结果缓存起来,下一次就直接拿出结果使用。cache最好在后期有了具体数据在进行,因为过早的优化,过早的加入cache机制不见得是正确的。为什么这么说呢?因为cache有一个可能失效甚至出错的可能,真正的结果可能因为某些数据变化而产生变化,如果这个时候cache系统不知道,那么就出错了,如果加入事件消息来刷新cache,也许就会让代码变得过于复杂,不容易维护和理解,也许性能还不如简单的版本快呢,就如同奥卡姆剃刀原理提到的那样,复杂的往往都是错的,或者是错误的根源。

    总结说就是使用正确的数据结构,适当使用cache。如果这些还不行,那就得具体问题具体分析,后来我加入了更详细的log信息,发现用户端对于同一个文件做了多次的初始化调用,这也是优化时候需要注意的,客户端代码也需要相应的优化,也许它们的优化才是最关键的。虽然没有拿到客户端优化的结果,但我相信这个修改会比我前面做的任何改进都要显著,而且未必改动很复杂。

    总的来说,这次代码改进不算是很成功,主要是一开始的方向不太对,尽管后来发现了真正的原因。我想主要问题是一开始就把目光聚集到非常微观的范畴里,导致大的问题没有得到解决。另外对于程序优化这件事,必须有实际的运行数据,猜测哪个地方可能会慢或者有问题,都是不客观的,在优化问题中,不应该出现“我觉得、我想”的字眼,什么地方慢什么地方需要改动,一定要用数据来说话。优化必然要对代码做这样那样的变动,这时候我们累积的test case就非常有用了,可以帮助我们确定代码改动是否引入了错误。