qt编译加速以及使用预编译头

方法

上次讲了如何使用预编译头来加速编译,现在给出一个Qt程序实际的例子,来演示 预编译头的好处.

我们采用qmake来编译Qt程序,qmake本身支持预编译头, 文档在这:http://doc.trolltech.com/3.3/qmake-manual-7.html

使用方法很简单,在pro文件里面加上这几行即可:

PRECOMPILED_HEADER = lib.hpp #头文件名
CONFIG += precompile_header #设置使用预编译头功能

示例

以下是我测试项目的例子. 文件目录:

halida@halida-desktop:~/temp/build-qt$ ls
build-qt.pro   lib.hpp    main.cpp   shower.cpp    shower.hpp

没有使用预编译头时消耗的时间:

halida@halida-desktop:~/temp/build-qt$ touch *.cpp
halida@halida-desktop:~/temp/build-qt$ time make>>/dev/null
real        0m7.292s
user        0m4.696s
sys         0m2.340s

使用预编译头后消耗的时间:

halida@halida-desktop:~/temp/build-qt$ touch *.cpp
halida@halida-desktop:~/temp/build-qt$ time make>>/dev/null
real        0m2.416s
user        0m1.324s
sys         0m1.004s
很明显,提升了相当多的速度.

例子可以在这里下载: http://linjunhalida.72pines.com/files/2010/09/build-qt.zip

Add comment 九月 3rd, 2010

如何使用预编译头,以及预编译头的原理

问题

在c/c++里面,如果一个xxx.c要暴露出接口给其他文件的话,一般是提供一个xxx.h的文件作为接口,然后其他文件会把xxx.h文件包含进自己里面去,这样就可以知道xxx.c提供了什么.

但是会出现这样的问题,如果一个xxx.h文件被包含了N次,那么项目在编译的时候,会把这部分的代码重复编译N次,当这个xxx.h文件非常大的时候,编译速度就很慢了.比如xxx.h代表了一个库.(Qt, windows等)

解法

为了解决这个问题,我们可以先把头文件编译好,然后再包含到其他文件里面去.这样,每个引用了该头文件的源文件就不需要再次编译这部分了.

示例

来自: http://stackoverflow.com/questions/58841/precompiled-headers-with-gcc

建立以下文件:

stdafx.h:

#include <string>
#include <stdio.h>

a.cpp:

#include "stdafx.h"
int main(int argc, char**argv)
{
  std::string s = "Hi";
  return 0;
}

编译和执行命令:

g++ -c stdafx.h -o stdafx.h.gch
g++ a.cpp
./a.out

删除了stdafx.h文件之后,执行g++ a.cpp照样编译成功.

实现的原理很简单:

  • 首先把一个stdafx.h头文件,编译成stdafx.h.gch.
  • 当执行g++ a.cpp的时候,g++编译器会先去找stdafx.h.gch,把它包含进来.这样就节省了编译时间.

如果stdafx.h被很多源文件引用,节省的编译时间是很可观的.

结论

利用预编译头文件,可以很明显地感觉到编译速度的提升.建议大家尝试一下.

还有一个有点相关的问题,如果修改了一个用到很多的头文件,就需要把所有用到这个头文件的源文件编译一遍,基本上等于重新编译了.所以,尽量少修改这种头文件.

2 comments 九月 1st, 2010

手机分配短讯id的面试题目

题目

TopLanguage论坛里有讨论一个面试题目,内容如下:

有个老的手机短信程序,由于当时的手机CPU,内存都很烂。所以这个短信程序只能记住256条短信,多了就删了。

每个短信有个唯一的ID,在0到255之间。当然用户可能自己删短信,现在我们收到了一个新短信,请分配给它一个唯一的ID。说白了,就是请你写一个函数:

byte function(byte* ids);

该函数接受一个ids数组,返回一个可用的ID,由于手机很破,我要求你的程序尽量快,并少用内存。注意:ids是无序的。

Miro的分析在这里: http://www.cnblogs.com/miloyip/archive/2010/08/31/idalloc_clarify.html

我的分析

我觉得,因为短消息发送的频率很低,那么我们不需要考虑取ID和释放ID的响应速度问题,主要问题放在如何节约空间.那么,最节约空间的是按照比特来存储ID是否使用.

还有就是,重新整理了需求,需要提供一个释放和获取ID的接口.

解法

代码如下,没有测过,保证有错:

#define SIZE_COUNT 256/8

struct manager {
    byte map[SIZE_COUNT];

    byte alloc();
    void dealloc(byte id);
};

//获取ID
byte alloc(){
    for(int i=0; i<SIZE_COUNT; i++){
        byte data = map[i];
        if (data == 255) continue; //全满了

        for(int j=0; j<8; j++){
            if (((data >> j) & 1) == 0) {
                //got it!
                data |= 1<<j;
                return i*8 + j;
            }
        }
    }
}

//释放ID
dealloc(byte id){
    map[id/8] &= ~(1<<(id % 8));
}

结论

上面的解法速度上还是很慢的,如果ID空间长期处于半饱和,那么每次获取都要循环一遍数组,那么效率无法接受,因此要考虑更复杂的链表方式,但是这样一来空间就不会最小了.

Add comment 九月 1st, 2010

为什么用ReST写博客

什么是ReST

ReST全称是reStructuredText,是一种容易写,容易看的文本格式,

具体介绍在这里: http://docutils.sourceforge.net/rst.html

如果你看不懂英文,可以看——好吧,我没有找到中文的介绍.

ReST的好处

好处就是:以后再也不用为了调整格式而费心啦,专心写文章.

当然了,遇到复杂的状况(比如写书,写公式,图表之类),还需要其他的工具.

对于写博客和简单的文档来说,是非常适合的.

如何发布到博客上

写好ReST后,把文本拷贝到: http://www.tele3.cz/jbar/rest/rest.html

这是一个在线生成工具,生成html之后,复制到博客里面发布就可以了.

记得保存备份,说不定以后什么时候还要用到的说.

结论

  • 中文资料比英文资料少多了,所以好好学英文吧.
  • 简单就是美.

Add comment 八月 31st, 2010

安利模式做教育

安利模式的问题

考虑安利的商业模式,每次交易发生在上线与下线之间,交易的成本是上线在下线身上投入的时间.

如果只是卖商品,直接营销的成本往往很大,而这部分成本是会转嫁给下线的,整个过程不会创造价值,或者整个体系的价值产出为负.

具体分析在这里: http://www.impencil.org/?p=7486

替代方案

我考虑了一下,如果采用教练指导作为商品,这样的模式可以带来价值.

因为:

  • 教练指导是对下线有价值的
  • 而这个价值不容易通过其他渠道来体现

什么是教练指导:

  • 在目标和方法都能够确定的前提下,教练指导学员一步步完成整个学习或训练过程.
  • 教练模式需要教练根据每个学员的状况作指导,必须是一对一的关系.
  • 普通人很难获得一个称职靠谱的教练.

作为商业模式来讲,下线可以通过上线的教育获得直接的收入提高,这个模式是可以带来价值的.

计划

这个模式的重点在于上线和下线的关系.为了保证这个模式成功,需要有以下几点:

  • 上线和下线能够保持一个稳定的关系
  • 下线还能继续发展下线
  • 防止体系”腐化”,像安利一样成为一个无法提供价值的体系

因此,考虑以下几个注意的方面:

  • 下线必须是”空白”人士,方便灌输
  • 上线拥有足够的指导能力,能够指导下线提升收入
  • 下线提升收入后,还是可以通过上线的指导继续提升
  • 上线鼓励下线发展下下线,提升双方的共同受益
  • 不会有滚雪球效应,防止其中一方独立门户

具体实施方法(初稿):

上线主动联系下线,说服下线,以工资收入的百分比方式获得教练费用.为了提升说服力,可以设定期望,没有满足期望的时候,上线返回若干钱.以合约的方式确立起来.

上线采用一系列方式教育下线,这个过程可以不是全职:上线最好有工作,才能保证上线自己足够的成长程度.

当上线无法提供价值给下线的时候,合约终止,因此上线必须时刻提升自己的价值产出.合约本身是制式文件,限制上线对下线采用洗脑的方式榨取收入,同时由于是双方签订合约,出现问题也与上线的上线无关.

上线可以通过培训下线的能力,让下线继续发展下下线,提升双方受益.

传输这样的观念:每个人必须要有教练,时刻监控自己的成长.

提供平台,让所有的成员都在这个平台上面交流,发展,防止社区分裂.

问题

以上只是初步的分析,但是也暴露出来几个问题点:

  • 如何吸引新人加入,收入分成的方法是不为绝大多数人接受的

    解法:需要这个体系能真正提升价值,然后新人才会希望加入

  • 如何保证关系持久,下线可能因为不值的原因取消合约,上线也可能因为不值的原因取消合约.

    解法:无法保证.但是可以让双方养成发展下线的习惯,新的合约建立速度大于旧的合约解除的速度即可.

  • 社区分裂:无法保证该模式不被其他人学去,并建立其他”邪恶”的组织.

    解法:需要能够提供一个稳定的,不会被夺取的上游价值提供源,比如通过该网络发送讯息,提升网络中人士的职业发展机会.这个平台直接通过上线下线获取收入和讯息,维持平台的运转.

结论

以上都是泛泛而论,需要通过进一步的实践来验证理论的有效和可行性.

Add comment 八月 31st, 2010

C语言如何实现raii

资源的获取与释放,C语言里面是要让程序员考虑的,比如:

void work(){
  Buffer b;
  init(b);
  do_sth(b);
  del(&b);
};

在C++里面,有raii这样很方便的特性,当离开作用域的时候,自动释放资源,如:

void work(){
  Buffer b;
  do_sth(b);
};

我在想,如何让C支持这样的特性?于是就有了下面这个宏:

#define using(b) \
for(int i=0; i<2; i++){\
if (i==0) \
  { init(b); } \
else \
  { if (i==1) \
    { del(b); \
      break; \
    }; \
  }; 

void work() {
  Buffer b;
  using(&b)
    printf("working..\n");
  };
};

edit: 被批了,C就按照C的方式干活,RAII交给C++.

Add comment 八月 27th, 2010

一个C解释器(伪)

我一直在用python,当遇到什么问题不确定的时候,我会打开python解释器,来验证自己的想法。
于是我想在C/C++里面采用同样的方法来处理。于是我去找C/C++解释器。
不过看起来不是很多,并且好像没有开源实现,至少我没有在我的ubuntu上面搜索到。
http://stackoverflow.com/questions/69539/have-you-used-any-of-the-c-interpreters-not-compilers
后来在toplanguage上面问了,建议是tinycc,不过我自己顺手写了一个脚本,实时编译执行,看起来还是挺好用的。需要python和gcc.
文件放在这里:http://dl.dropbox.com/u/1167873/cint

Add comment 八月 26th, 2010

gmail如何定时发邮件

gmail几乎成为我管理所有事情的工具了。但是有一个功能缺失:不能定时发邮件。

我的解决方案是采用lettermelatter.com这个网站的自动发邮件功能。

首先注册:http://www.lettermelater.com/。在网站上可以设置自动收发邮件。
但是我主要用的是另外一个强大的功能,可以通过发邮件给me@lettermelatter.com来设置收发邮件。

具体方法见:http://www.lettermelater.com/forum.php?id=2

不再翻译里面的内容,英语应该是每个人的基本功。

Add comment 八月 5th, 2010

网络教育——一个学生的故事

小王醒了。
他爬起来,洗漱,喝了微波炉里热好的豆浆,吃了面包。
然后打开了电脑。
电脑里面显示了一天的计划:
上午:经济学
下午:计算机算法导论
晚上:音乐欣赏

以及任务:
本周:
看完经济学课程推荐的3本书。
做完算法导论布置的习题。
听音乐欣赏布置的几首交响乐。

小王打起精神,开始点击播放经济学课程的视频。
他在一边看的同时,视频下方的聊天室显示出其他同学的留言。
大家在讨论理性人假设是否正确。

小王没有去管他,而是继续看视频。没有看完视频,他是没有参与讨论的资格的。
过了会,他看完了,讨论也结束了,助教给出了一个连接,解释大家的问题。
助教是学完课程的志愿者,他们通过帮助学习者,提升自己对问题的理解,以及回馈社区。
小王再看视频的时候,也产生了一些问题,在聊天室里面提出来了。又一个讨论开始了。
助教一直在帮助引导话题,在讨论快结束的时候,也给出一个连接。
“大家不要忘了周末前要交论文。”最后助教说。

小王发现自己有些问题在聊天室里不方便,于是用语音聊天联系了助教,请他帮忙。
然后一小段对话后,小王弄清楚了概念,道谢后断开了语音。

上午过了一半,虽然没有强制性质,但是小王还是继续下去看视频,
因为自己在助教的帮助下制定了学习计划,如果没有完成,那是对自己的不负责。

中午,小王吃完饭,出去走了走。回来睡了一个午觉。

下午,小王按照进度看完了视频,以及对应的课文章节。
在3点的时候,小王准时进入了一个语音视频聊天室。
算法导论需要做一个项目作为作业,他和几个网上的同学约好在这个时间讨论项目到底做什么。
那几个同学,有的在北京,有的在某个不致命的小城市,有的50岁了,有的还只是小孩。
但是他们都对这门课有兴趣,对项目有独到的见解。
讨论在4点准时结束,他们不只是讨论项目做什么,还按照任务作了分工。
“如果一个人完成不了,那我必须补上。”小王这样想,在计划表上,预留了下周的时间。

到了网上,做了一下午作业的小王,提交了作业给助教。打开了音乐播放器。
里面放的是音乐欣赏课布置要听的:动物狂欢节的《天鹅》。这对学习了一天的小王来说,是最好的休息。
然后小王走出家门,参加一个附近的读书会的活动。里面很多都是和他一样,网络学习的年轻人。
“他们会和我交流一天学习到的东西,互相鼓励。”

小王只是中国千千万万在线学习的年轻人中的一个。
他16岁,在父母的鼓励下,选择了网络教育。
“我没有把时间浪费在高考上面。”小王说。
小王初中毕业后,没有进入高中,
也因为家庭经济条件的关系,没有选择出国。
网络教育成为了他自己的选择。

“我的目标是改变世界。”
在参加了网络教育提供的测试,以及与多名教育专家的语音交流,小王定下了自己学习的计划。
经济学,计算机科学,音乐。
经济学让我了解社会,计算机科学让我能够做出用价值的产品,音乐使我一生不无聊。小王这样解释。
对于其他人问他,学完后怎么找工作,小王说:
“在学习的过程中,我会按照自己的意愿,给出很多个实际的项目出来。如果能够盈利,我就能够养活自己,即使不能盈利,我也能够通过这样的作品,说服企业雇用我。”

Add comment 八月 2nd, 2010

如果你因为想要赚钱,来学经济学,那你错了。

每次我向其他人推荐经济学书籍的时候,他们就会问:看完后是否能够用来赚钱?
我会告诉他们:不能,但是你能够看懂更多的社会现象,也是我为什么推荐这本书的原因。
然后,他们就把书放下了。
我理解他们为什么这样做。时间是宝贵的,在投入时间之前,要确认是否值得。
但是他们忽略了一点,一个人的眼界是有限的,如果只看自己眼界范围内的东西,对自己提高有限。

请回答以下问题:
你是否认为最低工资制度是好的?
你是否认为政府包办福利是好的?
你是否认为教育应该政府来抓?
你是否认为春节火车票价格过低了?
你是否认为有些关乎民生的产品,比如粮食要政府管制?
你是否认为有必要支持国货,抵制外国货?
你是否认为要打击房地产商屯地?
你是否认为要关闭全部的小煤窑?
你是否认为政府要作慈善?
你是否认为微软是垄断,要取缔?

如果以上有任何一个你选是,那么恭喜你,你有必要去学习经济学。
书在这里: http://book.douban.com/subject/1856927/

Add comment 八月 2nd, 2010

Previous Posts


标签

链接表

最近评论

文章