Linux mobile development

欢迎到Linux mobile development(www.limodev.cn)上交流。Limodev主要致力于基于linux的嵌入式系统的学习和研究,包括内核、驱动、GUI、MMI、软件设计方法和软件优化等方面,欢迎大家加入,无论是高手还是新手,一起学习共同进步。下载BLOG示例代码请先到limodev.cn/bbs上注册,谢谢

原创 探讨GTK+应用程序的优化方法收藏


探讨GTK+应用程序的优化方法

转载时请注明出处和作者联系方式
作者联系方式:李先静 <xianjimli at hotmail dot com>

随着应用程序功能的完善,时间和空间性能的优化已经成为我们目前工作的重心了。坦白的说,我并不擅长软件优化,甚至可以说我从心里不愿去做优化的工作,因为优化往往伴随破坏软件架构的副作用。但是到了目前这个阶段,整个系统在性能上的表现仍然不尽人意,已经不能再回避了。这里总结一下我所想到的基于GTK+应用程序的优化技巧,算是抛砖引玉吧,欢迎各位高手指教。

1.使用DirectFB作为GTK+的后端

DirectFB支持多进程模式,它用一个称为fusion的内核模块作为通信中介,用Master/Slave模型取代像TinyX所用的C/S模型,进行窗口操作时,不需要进程间切换,这在一定程度上改善了应用程序的响应速度。

2.使用DirectFB的pixbuf优化

DirectFB提供了一个pixbuf的主题引擎的优化实现,其实效果不错,我们在使用pixbuf的主题引擎时,感觉性能几乎没有下降。

3.延迟加载

强大的个人信息管理(PIM)是我们平台的特点之一,像名片,彩信,邮件,短信和日程等数据,我们没有加入硬性的限制,只受限于flash空间的大小。那么在显示列表时,一次性加载太多数据,必定会导致响应速度的急剧下降。为此我们对数据库和treeview做了一些改进,使用延迟加载的方式,只加载当前显示的和即将要显示数据,这不但节省了内存空间,也提高了响应速度。重要的是,加载速度随数据库容量的增加,只有微小的变化。

4.使用新的model代替model.clear

treeview和combobox等控件都使用了model,而model的特性是变化会通知view更新界面。这本来是它的优点,但有时在性能上却成为致命的因素,在重新刷新数据时,如果调用model的clear函数,该函数每删除一条数据都会触发一次signal让view更新,这使得重新加载数据变得非常非常慢。后来我们改为创建一个新的model,加载数据后再设置到view中,这样界面就只用更新一次。

同理,在第一次加载数据时,也要先把model的数据初始化好后,再设置到view里,而不是一条一条的插入进去,那样每插入一条都要更新一次界面,也会造成严重的性能影响。

5.Block signal

与前面一条类似,有的操作会触发signal,比如插入数据,会引发其它对象的更新。通常只是做一次操作,这没有什么问题,但在批量操作时,所造成的影响就变得显著了。这时可以先block住signal,等批量操作完成后,一次性触发signal。

6.在idle中加载数据

通常的做法是在应用程序初始化时,加载所有相关数据,这种方法让程序设计变得简单,但常常让应用程序起动变得缓慢。起动变得慢了,可能会让用户误以为没有点中起动图标,而多次重复去点击起动图标,造成重复起动应用程序,虽然我们可以保证应用程序单实例运行,但仍然会有一些系统开销,更重要的是起动缓慢会让用户不满意。这时可以先显示界面,让数据加载在idle里完成,等用户真正去操作界面时,数据也加载得差不多了。

7.使用动画标识当前的状态

这个方法并不能提高程序的速度,相反还有一些系统开销,不过它可以让用户知道当前状态,而不至于在界面没有反应时抓狂。这可以在应用程序起动过程中,显示一个动画标识正在起动,我们支持startup-notification功能,所以可以在桌面里统一处理,而应用程序自身不需要关心。

8.Prelink

prelink的功能正如其名字所示,事先link好所有共享库,避免在加载时才link带来的开销。它不仅可以加快起动速度,还可以减少内存开销。不过它虽然有点效果,但不要对它指望太高。

9.去掉DirectFB中不必要的驱动程序。

以前发现DirectFB中有很多共享库,它们是用于显卡加速的,里面有空间不小的data段,由于这些data段是私有的,而且它们在很多进程中加载,所以占去不少空间。我们并不需要这些加速驱动程序,可以直接删除它们。

10.只读数据用const修饰

我们知道const数据是放在rodata段中的,它在所有进程之间共享,即只加载一份拷贝。而普通数据是放在data段里的,它是进程私有的,每个进程都要加载一份拷贝。所以对于只读的数据,一定要加const修饰符,让数据放在rodata段中,可以节省不少内存空间。

11.尽量减少进程数

进程数的增加对于内存有很大影响,这不仅是因为内核创建进程时所占的空间,更重要的是,一般的进程都会链接很多共享库,每个共享库的中data/bss都要分配私有空间,最终占去很大的RAM空间。所以减少进程数对RAM空间的节省有明显的效果,合并进程,同时减少了进程间的通信开销,这也有利于提高时间性能。我们把SCIM从7个进程合并为两个进程后,输入法的响应速度有明显提高,占用的RAM空间也减少了。我们现在着手进一步合并后台服务进程。

12.使用Thumb指令代码ARM指令

Thumb是16位的,把程序编译成thumb指令,可以大大降低代码段的大小,不但节省了flash空间也节省了RAM空间。同时由于数据总线是16位的,程序的运行速度较ARM指令也有很大提高。我们目前正在研究,从可行性上讲,应该没有什么问题。

13.减少不必要的依赖。

前面说了共享库的data/bss段是私有的,每个进程都有一份拷贝。而gcc并没有在链接时做优化处理,不管你是否真正调用了某了个库的函数,只要在命令行参数指定该库,它就会链接进来。所以在创建Makefile时,一定要尽量避免链接不必要的共享库。

附带说明一下,linux的内核虽然实现了父子进程之间的Copy on write技术,避免不必要的内存复制,但这对data/bss段并没有什么意义,原因是fork之后,在执行exec之类的函数时,整个进程空间已经被替换了。data/bss并不会在父子之间共享,相反,它们立即就被创建并初始化。

14.Minimo用gtk编写而不用XUL编写

我们用gtk重写minimo之后,minimo起动速度由原来的40秒,提高到了后来的7秒,看来XUL的性能表现确实不佳。后来又采用idle加载机制,现在从起动到显示界面仅要2到3秒钟的时间。

15.dlopen 代替exec

我记得ALP使用了这一招,据说效果不错。它把应用程序编译成共享库而不是可执行文件,在执行时先fork一个进程,再通过dlopen把应用程序加载进来运行。这样仍然是多进程的,但是避免了exec这样的费时的操作,同时可以享受父子进程之间的copy on write技术带来的性能提升。不过令人我惊异的是,我的实验结果得到却是相反的数据,有时间我再分析一下。

16.cache压缩

有一种称为cache压缩的技术,它可以让cache压缩后存放在内存中,把省出的空间供其它进程使用。我们还没有来得及测试,有兴趣的朋友可以参考http://linuxcompressed.sourceforge.net

17.Gtkrc cache

据说Nokia的N770/N800为加快应用程序的起动速度,使用了一种称为gtkrc cache的技术,具体细节不太清楚,大概可能是把gtkrc从原始的文本文件存为二进制文件,使得gtkrc的加载速度变快吧。

18.XIP

XIP可以让应用程序直接在norflash中执行,而不必加载的内存中执行。我们没有使用norflash,所以也就没有去研究,不过这种思想倒是挺不错的。

19.使用压缩的文件系统

像ramfs,jffs 2和yaffs 2等文件系统都可以压缩,压缩比率也相当可观,能够节省大量的flash空间。我们目前使用的jffs 2,据说yaffs 2表现更为优异,等测试之后,再决定最终使用哪一种吧。

20.挖掘硬件加速功能

现在的CPU一般都带有硬件加速功能,特别是多媒体相关的应用,比如硬件编解码和MMX指令等等,这对多媒体应用程序相当有效,要充分发挥,不用白不用,不要浪费了。

21.使用更小的函数库

现在不少函数库,都有多种实现,可以考虑使用针对嵌入式设备优化过的版本。比如uclibc代替glibc等等,虽然介于以前使用uclibc的经验,我决不赞成使用uclibc,但类似的方法还是可取的。

22.奉行简约主义

像词典的词库,输入法的词库和字体等数据,都要尽量精简到最少,不能像PC那样有多少就放多少。

在以上方法中,有的可以同时提高时间和空间性能,有的只能提高时间性能或者空间性能,还有的是时间性能和空间性能互换的,要根据具体情况进行取舍。

希望各位高手不吝赐教。

~~end~~
 

发表于 @ 2007年09月17日 20:20:00|评论(loading...)|收藏

新一篇: X Window研究笔记(7) | 旧一篇: X Window研究笔记(6)

用户操作
[即时聊天] [发私信] [加为好友]
李先静
订阅我的博客
XML聚合  FeedSky
李先静的公告

BLOG评论请到


下载BLOG示例代码请先到上注册,谢谢。

文章分类
收藏
1.友情链接
0华清远见-嵌入式培训专家
aimself@CSDN(RSS)
directfb中文网站(RSS)
Eric's Little Hut
eye_of_back的专栏(RSS)
Linux Mobile Research
Phoenix@上海(RSS)
segments的专栏(RSS)
study's Blog(RSS)
tracestudio
伐木丁丁鸟鸣嘤嘤(RSS)
会飞的鱼的专栏(RSS)
创系的技术博客
小四的BLOG(RSS)
小马哥的博客(RSS)
开源电信(RSS)
御风剑客
新奇的BLOG
易军军的网络家
李吉群的专栏(RSS)
2.亲情链接
凤凰的幸福蓄水池(RSS)
我的相册
3.软界高手
Donald E. Knuth (RSS)
孟岩(RSS)
透明(RSS)
4.LinuxMobile
celinuxforum(RSS)
GPE(RSS)
maemo.org(RSS)
opensource.motorola
palowireless
5.XWindow
Jserv's blog(RSS)
Keith Packard(RSS)
6.技术资源
7.开源项目
freedesktop(RSS)
GNU(RSS)
GTK+(RSS)
matchbox(RSS)
pxa27x-linux/
8.我的BLOG镜像
absurd@chinaunix
absurd@msn
My English BLOG(RSS)
存档
Csdn Blog version 3.1a
Copyright © 李先静