2006年7月3日

由于工程的文件的日益庞大和第3方库(ACE Loki Boost等等)的使用增多
我所工作的项目系统构建时间从最初的3分钟变为现在的8分钟
程序员的机器配置已经很不错了,3。0 的主频1g的内存,但是常常由于一个小的修改导致5分钟甚至更长的编译时间来验证效果。

按照《Joel on software》的说法,其直接后果是可怕的:
程序员们在这8分钟内无所事事,只有查看网页,或者qqmsn,打断先前的思路从他们的上下文环境里面脱离了出来,离开了“顺势工作时间”,等到他们编译好了验证再修改的时候,他们又得花不少的时间来回到刚才的思路

“顺势工作时间”大致意思就是说2个不连续的半小时的效果远不如一个连续沉浸的1小时的工作效果,如果一个人不能连续沉浸的思考,那么他就很可能陷入在不停的上下文环境切换和浅表思考当中。人的多线程处理和机器是一样的环境的切换不能够不考虑

所以,在当前机器配置已经没有什么提升空间的情况下,我在项目组内部组织了一次整改活动,旨在降低编译构建时间


1。目标:将完全重新编译时间从8分钟降低到4分钟以下
2。原则:通过和主程序的沟通,并参考了《C++ coding Standards》出了一下几条整改原则:
     首先是关于include的,因为包含头文件相当于将代码复制到本文件来编译,而头文件又经常是用来被别人包含的,所以工程文件多了,每个文件都有include链(包含的文件又include了其他文件),该链条不会止步于你工程,而会延伸到你所有使用的第3方库里面

     A.能够去掉的include就去掉。

     B.能够在cpp里面include的头文件不要在头文件里面include。
     
说明:尽量去掉每个cpp会被串起来的头文件膨胀的机会

     C.能够用前向声明的就不要include,头文件里面也是一样
     说明:在头文件里面用前向声明然后保存指针或者引用,在具体实现的cpp里面再包含头文件,虽然看起来和《C++ coding Standards》“Make header files self-sufficient”有些冲突(前两天另外cppblog一位朋友讲过http://www.cppblog.com/flyingxu/archive/2006/06/23/8908.html)但是在一些核心的.h(被很多类include的)里面作改造工作,还是能够收到很大的降低编译时间效果,而付出的代价就是原来只需要包含该头文件就可以编译成功的cpp需要额外包含一些头文件。

举个例子: Foo类头文件使用了前向申明保存了A类和B类的指针或者引用为成员变量,在Foo类的cpp里面才包含A和B的头文件,而当C类需要使用Foo类时候包含Foo类的头文件,但是操作中又需要调用A的成员函数,C不同时包含A的头文件的花就会出现编译失败。

虽然表面上是让代码更加复杂了,但是除却带来降低编译时间的好处之外,代码也在强迫你进行解耦合,如果说你cpp里面需要包含的头文件越多,说明你这个类需要知道的对象就越多,你可以乘机检查一下自己的代码又没有不必要的耦合,为什么这个cpp需要知道那么多的本来可能属于别的类的细节.....

      D。把大多数模块都要使用的库文件或者稳定类的头文件include放到预编译头文件“stdafx.h”里面
      
说明:由于预编译头文件里面include的内容只会compile一次而被link多次,把一些常用类放到这里会降低很多编译时间,但也不能乱来,要点在于 “大多数”和“稳定”,如果一个头文件经常变化,他的一次小改动都会引起整个工程rebuild,哪怕只是一个注释,因为所有的cpp文件都包含了stdafx.h而stdafx.h又包含了这个容易变动的头文件。
      
      E.使用Pimpl惯用法
      说明:关于Pimpl大家可以查下资料,《C++ coding Standards》里面也有讲解,基本上就是采用一个私有的前向申明的stuct指针把所有protect成员都封装起来起来.基本上是一个最终极的解决方案,但是对我们现有架构改造太大,不敢全面实行,我们只选择了数个最有价值的类进行了改造,打算以后在其他项目里面再全面应用。

3。实施: 通过半个小时的沟通,让项目组程序员了解原则,并采取结队修改的方式来降低引入新bug的风险,在以通过原有单元测试用例的条件下,进行修改-测试-提交的迭代。   

4。结果:   编
译时间降低到了6分钟以内。。。虽没有达到预期,但也算有效果,没有完全达标的主要原因还是没有完整的测试方案包括单元测试和验收测试,怕有些改动过大影响系统健壮性,局部放弃了一些实施的原则。


把这个整改的工作写出来,一方面作个记录,另外一方面希望和大家讨论,相互多多交流:)


ps:
希望有过类似工作的朋友加我的
MSN:itso2_at_msn.com
大家多多沟通
posted @ 2006-07-03 15:43 天爬者 阅读(1362) | 评论 (4)编辑 收藏

2006年5月23日

公司有一个项目从vs2003移植到vs2005之后老是出现runtim erro
经过排查最终定位在fstream 打开"含中文路径"的文件时候会出现fail的情况
本来不相信vs2003过渡到2005会有这个问题,但是经过试验确证实了该问题
我新建立一个exe来测试该问题

 1#include "stdafx.h"
 2#include "testiostream.h"
 3#include <string>
 4#include <fstream>
 5
 6
 7BEGIN_MESSAGE_MAP(CtestiostreamApp, CWinApp)
 8END_MESSAGE_MAP()
 9
10CtestiostreamApp::CtestiostreamApp()
11{
12}

13
14CtestiostreamApp theApp;
15
16BOOL CtestiostreamApp::InitInstance()
17{
18    CWinApp::InitInstance();
19    std::ifstream iput;
20    iput.open("F:\\中文.txt");
21    ASSERT(!iput.fail());
22    return FALSE;
23}

vs2003不需要作任何设置就可以就可以成功
但是vs2005下每次都会失败在断言处,查找了一些网上资料,例如
http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=371229&SiteID=1
发现但凡是uinicode的路径都是有该问题的.
解决方法有2个
1.第一个使用vs2005默认的unicode set并在所有字符串外面面加上_T() 或者_TEXT宏,代价是原来所有不符合unicode规范的地方你都必须得改.
2.使用not set 或者"mutibyte set" 并在程序初始化的时候调用setlocale()如下

BOOL CtestiostreamApp::InitInstance()
{
     setlocale(LC_ALL,
"Chinese-simplified");
    CWinApp::InitInstance();
    std::ifstream iput;
    iput.open(
"F:\\中文.txt");
    ASSERT(
!iput.fail());
    
return FALSE;
}
就可以解决该问题

上述引用的ms论坛连接基本讲清楚了该问题,但是由于我前几日搜索中文相关信息时候,实在未发现有用之内容,故记录下来,希望有相同问题又不思其解的朋友可以少花点时间.
posted @ 2006-05-23 08:49 天爬者 阅读(3881) | 评论 (3)编辑 收藏

2006年5月18日

最近研究自动化构建系统(持续集成),最终发现finalbuilder十分之好用

根据网上

http://blog.dream4ever.org/dirt/archive/2005/12/20/79946.drl 

这篇文章,初步作了一个 由subversion 的post-commit 触发的自动更新所有相关代码编译,并把编译结果以及信息发送给相关人员的邮件的finalbuilder工程,目的是期望所有程序员能够养成一种提交可编译代码的习惯,

其中需要用到一种叫做 subversion info 的action 类型, 其原理大概是调用 subversion/bin 里面的 svn.exe 加上参数 info 然后从标准输出中匹配相关信息取得特定数据放到 指定的变量中,但是其action始终不能执行成功,更别提保存我需要的变量了.

经过一系列试验,估计是由于svn在中文操作系统上返回的是类似下面的中文信息

C:\Program Files\Subversion\bin>svn info D:\LocalSvnForDailyBuild\dest
路径:D:\LocalSvnForDailyBuild\dest
地址(URL):http://192.168.1.100:3115/dest
Repository Root: http://192.168.1.100:3115/dest
档案库 UUID:47b214da-b8ec-df4b-aac3-16e2c895fbbd
修订版:666
节点种类:目录
调度:正常
最后修改的作者:medicer
最后修改的修订版:666
最后修改的时间: 2006-05-18 11:58:03 +0800 (星期四, 18 五月 2006)
属性最后更新: 2006-05-15 10:41:52 +0800 (星期一, 15 五月 2006)

而finalbuilder期望的估计是英文的输出,所以匹配不了导致失败

经过几番试验

最后把subversion 目录 C:\Program Files\Subversion\share\locale\zh_CN\LC_MESSAGES\subversion.mo 文字信息文件删除掉后,svn返回都使用了默认的英文,而finalbuilder也终于运行成功, 最后一次提交者提交时间都能够正常取到!

没有什么技术含量,只是在这里记录下来,希望遇到相同问题的朋友可以搜索得到,不用再折腾 

posted @ 2006-05-18 14:29 天爬者 阅读(1762) | 评论 (2)编辑 收藏
仅列出标题