项目越来越大,每次需要重新编译整个项目都是一件很浪费时间的事情。Research了一下,找到以下可以帮助提高速度的方法,总结一下。
1. 使用tmpfs来代替部分IO读写
2.ccache,可以将ccache的缓存文件设置在tmpfs上,但是这样的话,每次开机后,ccache的缓存文件会丢失
3.distcc,多机器编译
4.将屏幕输出打印到内存文件或者/dev/null中,避免终端设备(慢速设备)拖慢速度。
tmpfs
有人说在Windows下用了RAMDisk把一个项目编译时间从4.5小时减少到了5分钟,也许这个数字是有点夸张了,不过粗想想,把文件放到内存上做编译应该是比在磁盘上快多了吧,尤其如果编译器需要生成很多临时文件的话。
这个做法的实现成本最低,在Linux中,直接mount一个tmpfs就可以了。而且对所编译的工程没有任何要求,也不用改动编译环境。
mount -t tmpfs tmpfs ~/build -o size=1G
用2.6.32.2的Linux Kernel来测试一下编译速度:
用物理磁盘:40分16秒
用tmpfs:39分56秒
呃……没什么变化。看来编译慢很大程度上瓶颈并不在IO上面。但对于一个实际项目来说,编译过程中可能还会有打包等IO密集的操作,所以只要可能,用tmpfs是有益无害的。当然对于大项目来说,你需要有足够的内存才能负担得起这个tmpfs的开销。
make -j
既然IO不是瓶颈,那CPU就应该是一个影响编译速度的重要因素了。
用make -j带一个参数,可以把项目在进行并行编译,比如在一台双核的机器上,完全可以用make -j4,让make最多允许4个编译命令同时执行,这样可以更有效的利用CPU资源。
还是用Kernel来测试:
用make: 40分16秒
用make -j4:23分16秒
用make -j8:22分59秒
由此看来,在多核CPU上,适当的进行并行编译还是可以明显提高编译速度的。但并行的任务不宜太多,一般是以CPU的核心数目的两倍为宜。
不过这个方案不是完全没有cost的,如果项目的Makefile不规范,没有正确的设置好依赖关系,并行编译的结果就是编译不能正常进行。如果依赖关系设置过于保守,则可能本身编译的可并行度就下降了,也不能取得最佳的效果。
ccache
ccache工作原理:
ccache也是一个编译器驱动器。第一趟编译时ccache缓存了GCC的“-E”输出、编译选项以及.o文件到$HOME/.ccache。第二次编译时尽量利用缓存,必要时更新缓存。所以即使"make clean; make"也能从中获得好处。ccache是经过仔细编写的,确保了与直接使用GCC获得完全相同的输出。
ccache用于把编译的中间结果进行缓存,以便在再次编译的时候可以节省时间。这对于玩Kernel来说实在是再好不过了,因为经常需要修改一些Kernel的代码,然后再重新编译,而这两次编译大部分东西可能都没有发生变化。对于平时开发项目来说,也是一样。为什么不是直接用make所支持的增量编译呢?还是因为现实中,因为Makefile的不规范,很可能这种“聪明”的方案根本不能正常工作,只有每次make clean再make才行。
安装完ccache后,可以在/usr/local/bin下建立gcc,g++,c++,cc的symbolic link,链到/usr/bin/ccache上。总之确认系统在调用gcc等命令时会调用到ccache就可以了(通常情况下/usr/local /bin会在PATH中排在/usr/bin前面)。
安装的另外一种方法:
vi ~/.bash_profile
把/usr/lib/ccache/bin路径加到PATH下
PATH=/usr/lib/ccache/bin:$PATH:$HOME/bin
这样每次启动g++的时候都会启动/usr/lib/ccache/bin/g++,而不会启动/usr/bin/g++
效果跟使用命令行ccache g++效果一样
这样每次用户登录时,使用g++编译器时会自动启动ccache
继续测试:
用ccache的第一次编译(make -j4):23分38秒
用ccache的第二次编译(make -j4):8分48秒
用ccache的第三次编译(修改若干配置,make -j4):23分48秒
看来修改配置(我改了CPU类型...)对ccache的影响是很大的,因为基本头文件发生变化后,就导致所有缓存数据都无效了,必须重头来做。但如果只是修改一些.c文件的代码,ccache的效果还是相当明显的。而且使用ccache对项目没有特别的依赖,布署成本很低,这在日常工作中很实用。
可以用ccache -s来查看cache的使用和命中情况:
cache directory /home/lifanxi/.ccachecache hit 7165cache miss 14283called for link 71not a C/C++ file 120no input file 3045files in cache 28566cache size 81.7 Mbytesmax cache size 976.6 Mbytes
可以看到,显然只有第二编次译时cache命中了,cache miss是第一次和第三次编译带来的。两次cache占用了81.7M的磁盘,还是完全可以接受的。
distcc
一台机器的能力有限,可以联合多台电脑一起来编译。这在公司的日常开发中也是可行的,因为可能每个开发人员都有自己的开发编译环境,它们的编译器版本一般是一致的,公司的网络也通常具有较好的性能。这时就是distcc大显身手的时候了。
使用distcc,并不像想象中那样要求每台电脑都具有完全一致的环境,它只要求源代码可以用make -j并行编译,并且参与分布式编译的电脑系统中具有相同的编译器。因为它的原理只是把预处理好的源文件分发到多台计算机上,预处理、编译后的目标文件的链接和其它除编译以外的工作仍然是在发起编译的主控电脑上完成,所以只要求发起编译的那台机器具备一套完整的编译环境就可以了。
distcc安装后,可以启动一下它的服务:
/usr/bin/distccd --daemon --allow 10.64.0.0/16
默认的3632端口允许来自同一个网络的distcc连接。
然后设置一下DISTCC_HOSTS环境变量,设置可以参与编译的机器列表。通常localhost也参与编译,但如果可以参与编译的机器很多,则可以把localhost从这个列表中去掉,这样本机就完全只是进行预处理、分发和链接了,编译都在别的机器上完成。因为机器很多时,localhost的处理负担很重,所以它就不再“兼职”编译了。
export DISTCC_HOSTS="localhost 10.64.25.1 10.64.25.2 10.64.25.3"
然后与ccache类似把g++,gcc等常用的命令链接到/usr/bin/distcc上就可以了。
在make的时候,也必须用-j参数,一般是参数可以用所有参用编译的计算机CPU内核总数的两倍做为并行的任务数。
同样测试一下:
一台双核计算机,make -j4:23分16秒
两台双核计算机,make -j4:16分40秒
两台双核计算机,make -j8:15分49秒
跟最开始用一台双核时的23分钟相比,还是快了不少的。如果有更多的计算机加入,也可以得到更好的效果。
在编译过程中可以用distccmon-text来查看编译任务的分配情况。distcc也可以与ccache同时使用,通过设置一个环境变量就可以做到,非常方便。
总结一下:
tmpfs: 解决IO瓶颈,充分利用本机内存资源
make -j: 充分利用本机计算资源
distcc: 利用多台计算机资源
ccache: 减少重复编译相同代码的时间
这些工具的好处都在于布署的成本相对较低,综合利用这些工具,就可以轻轻松松的节省相当可观的时间。上面介绍的都是这些工具最基本的用法,更多的用法可以参考它们各自的man page。
5.还有提速方法是把屏幕输出重定向到内存文件或/dev/null,因对终端设备(慢速设备)的阻塞写操作也会拖慢速度。推荐内存文件,这样发生错误时,能够查看。
‘贰’ Xcode 构建速度优化(一)衡量编译时间
随着项目不断迭代,工程文件越来越多,引用的三方库也越来越多,这些直接导致编译时间的不断增加,完整编译一次项目动辄需要五分钟以上时间,实在有些影响开发效率,是时候来一波提速了。
为编译和构建提速,首先我们需要对速度有一个衡量标准:准确获得构建用时
首先,我们需要定义要衡量和优化的内容。 有两种选择:
xcode默认情况下会跟踪所有构建,我们可以通过更改xcode相关设置,来在活动查看器中显示出构建时间,通过命令行:
每次编译成功后,会在Successed之后显示出所用时间:
Xcode Build Timing Summary是Xcode10中加入的用于查看获取构建时间和发现用时瓶颈方面的最有利工具。 可以通过Proct->Perform Action->Build With Timing Summary来开启:这样在 Build Log 的末尾就会添加 Timing Summary Log。我们可以通过这个 log 看到哪个阶段是耗时的,便于我们进行优化。
如上图中: xib阶段的编译耗时明显是比普通c文件要多的,意味着我们可以通过减少xib方式来优化提升速度
而c文件的编译用时比总时间还要长,是因为c文件是并行编译的
在命令行中同样可以开启这个功能:
常用的第三方工具有 BuildTimeAnalyzer 、 xcode-build-times-rendering 、 XCLogParser 。
BuildTimeAnalyzer可以统计可以得出某个文件的类型检查时长,每个表达式的类型检查时长。
xcode-build-times-rendering是一个Ruby编写的第三方工具,可以方便地分别测量目标的构建时间并在图表上显示它们,使用gem安装
接下来使用这个工具自带命令配置项目
然后构建项目并生成报告:
这个工具使用上比较简单,缺点是只能从宏观上生成各个target编译的整体图标,无法详细列出各个内部编译明细
XCLogParser可以详细列出各个Target和内部每个文件的编译耗时,对我们分析编译时间瓶颈非常有帮助,它的工作原理主要是做为解析器,通过解析xcode编译生成的xcactivitylog日志来记录
安装:
编译项目后,进行安装
安装成功后通过命令:
会自动在当前目录的 build/xclogparser/reports/ 路径下生成报告,其中--project参数需要设置为待分析项目的名字,并注意当前在终端切换到希望写入日志的目录。
报告截图:
这个工具将作为我们后面分析提升编译构建速度的主要使用工具。
经过我多次在不同时间段,不同电脑上不断尝试编译,
我发现编译耗时是一个比较玄的东西,及时在同一台电脑,同一个项目, 同一套环境配置下,编译用时也会随着电脑当前状态(包括同时打开进程、散热等等)上下大幅跳动,就像算法时间复杂度一样,有时候我们明明做了一些细微的优化,但是结果反而是编译耗时增加了,这是很正常的事情
所以,衡量这个标准需要我们取多次试验中的平均值作为参考。
‘叁’ 5涓浼桦寲浠g爜镄勫皬鎶宸т笓涓氩︾敓𨱒ョ湅
5涓浼桦寲Python 浠g爜镄勫皬鎶宸
璁╀綘浠g爜镟翠笂涓灞傛ゼ
5涓浼桦寲Python浠g爜镄勫皬鎶宸
1.镐ц兘浼桦寲镄勫垎鏋
鍒嗘瀽鏄娴嬮噺鍜屽垎鏋愪唬镰佺殑镐ц兘浠ヨ瘑鍒镐ц兘鐡堕堢殑杩囩▼銆侾ython
鎻愪緵浜嗗唴缃镄勬ā鍧楋纴 濡俢 Profile鍜宼ime it锛 鍙浠ョ敤𨱒ヨ繘琛屽垎鏋愩
鍙浠ヤ娇鐢╟ Profile𨱒ュ垎鏋愪唬镰佷腑涓嶅悓鍑芥暟鎴栨柟娉曟墍鑺辫垂镄勬椂闂达纴
浣跨敤time it𨱒ユ祴閲忕壒瀹氢唬镰佺墖娈电殑镓ц屾椂闂淬傝繖閲屾湁涓涓绀轰緥锛
鍦ㄦょず渚嬩腑锛 瀵逛袱涓鍑芥暟slow_function鍜宖ast_function杩
琛屽垎鏋愶纴浠ユ祴閲忓畠浠镄勬墽琛屾椂闂淬傚垎鏋愮粨鏋滃彲浠ュ府锷╃‘瀹氩摢涓鍑
鏁扮殑镓ц屾椂闂存洿闀匡纴鍙浠ヨ繘涓姝ヤ紭鍖栥
2.浼桦寲鏁版嵁缁撴瀯
阃夋嫨姝g‘镄勬暟鎹缁撴瀯鍙浠ユ樉镢楀奖鍝峆ython浠g爜镄勬ц兘銆
Python鎻愪緵浜嗗氱嶅唴缃镄勬暟鎹缁撴瀯锛 濡傚垪琛ㄣ佸厓缁勚侀泦钖埚拰瀛
鍏革纴姣忎竴绉岖粨鏋勯兘链夎嚜宸辩殑鐗圭偣鍜屾ц兘銆备负涓涓鐗瑰畾镄勭敤渚嬮夋嫨
链钖堥傜殑鏁版嵁缁撴瀯鍙浠ユ瀬澶у湴浼桦寲浠g爜镓ц屻傝繖閲屾湁涓涓绀轰緥锛
鍦ㄦょず渚嬩腑锛屾瘆杈冧简涓ょ嶆柟娉曟潵鍒涘缓涓涓浠0鍒9999镄勬暟瀛楀垪琛
銆傜涓绉嶆柟娉曟槸鍦ㄤ竴涓寰鐜涓浣跨敤鍒楄〃杩炴帴锛岀敱浜庢疮娆¤凯浠i兘瑕
鍒涘缓鏂扮殑鍒楄〃锛屾墍浠ヤ细瀵艰嚧镐ц兘涓崭匠銆傜浜岀嶆柟娉曚娇鐢ㄥ垪琛ㄧ悊瑙
锛岃繖绉嶆柟娉曟洿链夋晥锛屾洿浼桦寲銆
3.鍒╃敤鍐呯疆镄勫嚱鏁板拰搴
Python鎻愪緵浜嗕竴濂椾赴瀵岀殑鍐呯疆鍑芥暟鍜屽簱锛 杩欎簺鍑芥暟鍜屽簱閮芥槸缁
杩囨ц兘浼桦寲镄勚备娇鐢ㄨ繖浜涘唴缃鍑芥暟鍜屽簱鍙浠ュぇ澶ф彁鍗嘝ython浠
镰佺殑镐ц兘銆傝繖閲屾湁涓涓绀轰緥锛
鍦ㄦょず渚嬩腑锛屾瘆杈冧简涓ょ嶅逛竴涓鏁板瓧鍒楄〃杩涜屾帓搴忕殑鏂规硶銆傜涓
绉嶆柟娉曚娇鐢ㄤ竴涓镊瀹氢箟镄勬瘆杈冨嚱鏁帮纴 鐢变簬lambda鍑芥暟镄勪娇鐢锛
瀹幂殑阃熷害浼氭瘆杈冩参銆傜浜岀嶆柟娉曞皢鍏跺垹闄わ纴 浣跨敤甯︽湁榛樿key鍙
鏁扮殑sorted鍑芥暟锛 杩欑嶆柟娉旷粡杩囦紭鍖栵纴 鏁堢巼镟撮珮銆
4.鍒╃敤鍗虫椂缂栬疟(JIT)
缂栬疟鍣↗ust-In-Time(JIT) 缂栬疟鏄涓绉嶅彲浠ュ湪杩愯屾椂锷ㄦ佷紭鍖
鍜岀紪璇戦儴鍒嗕唬镰佷互鎻愰珮鍏舵ц兘镄勬妧链銆侾ython鎻愪緵浜呙IT缂栬疟搴
锛 濡侾yPy鍜孨umba锛 鍙浠ョ敤𨱒ヤ紭鍖栨ц兘鍏抽敭镄勪唬镰併傜湅涓嬮溃
镄勭ず渚嬶细
鍦ㄦょず渚嬩腑锛 浣跨敤numba搴揿逛竴涓璁$畻鏂愭尝闾e戞暟鍒楃殑阃掑綊鍑
鏁拌繘琛屼简JIT缂栬疟銆侸IT缂栬疟鍦ㄨ繍琛屾椂浼桦寲浜呜ュ嚱鏁帮纴 涓庨潪浼桦寲鐗
链鐩告瘆锛屾ц兘寰楀埌浜嗘彁楂樸
5.绠$悊鍐呭瓨浠ュ疄鐜版ц兘浼桦寲
链夋晥镄勫唴瀛樼$悊鍙浠ユ瀬澶у湴褰卞搷Python浠g爜镄勬ц兘銆傝稿傚唴瀛
鍒嗘瀽銆佸瀮鍦炬敹闆嗗拰鍏锋湁鍐呭瓨楂樻晥镄勬暟鎹缁撴瀯绛夋妧链鍙浠ョ敤𨱒ヤ紭鍖
鍐呭瓨镄勪娇鐢ㄥ苟鍑忓皯鍗犵敤銆傝繖閲屾湁涓涓绀轰緥锛
鍦ㄦょず渚嬩腑锛 姣旇缉浜嗕袱绉崭娇鐢∟umPy瀵逛袱涓澶ф暟缁勮繘琛屼箻娉旷殑
鏂规硶銆傜涓绉嶆柟娉曟槸浣跨敤甯歌勭殑鏁扮粍涔樻硶锛屽畠鍒涘缓浜嗕腑闂存暟缁勶纴
鍙鑳戒细瀵艰嚧浣庢晥镄勫唴瀛树娇鐢ㄣ傜浜岀嶆柟娉曚娇鐢ㄨ嗗浘鍜屽箍鎾𨱒ヤ紭鍖
鍐呭瓨浣跨敤骞跺噺灏戝崰鐢ㄣ
‘肆’ 为什么在使用vs2010时编译c++程序时候速度特别慢,而以前用vc6时快得多
两个方法:
1.在工程下按Alt+F7打开Properties
1.1
在General里whole program optimization,将选项调整到use link time code generation
1.2
在C/C++选项卡下的general把multi-processor compilation设置为YES
‘伍’ Java鍜孋/C 缂栬疟鍣ㄦ帹钻
鎺ㄨ崘浣跨敤Eclipse鍜孖ntelliJ IDEA銆丢CC鍜孋lang銆
Eclipse鏄涓娆惧箍娉涗娇鐢ㄧ殑Java闆嗘垚寮鍙戠幆澧冿纸IDE锛夛纴瀹冨叿链夊己澶х殑缂栬疟鍜岃皟璇曞姛鑳斤纴浠ュ强瀵笿ava璇瑷鐗规х殑镩濂芥敮鎸併侲clipse𨰾ユ湁涓板瘜镄勬彃浠剁敓镐佺郴缁燂纴鍙浠ユ牴鎹闇瑕佽繘琛屽畾鍒跺拰镓╁𪾢銆傚洜姝わ纴镞犺烘槸鍒濆﹁呰缮鏄缁忛獙涓板瘜镄勫紑鍙戣咃纴Eclipse閮芥槸涓涓鍊煎缑鎺ㄨ崘镄凧ava缂栬疟鍣ㄣ
IntelliJ IDEA鏄涓娆惧姛鑳藉己澶х殑Java IDE锛屾彁渚涗简鏅鸿兘浠g爜缂栬緫銆侀吨鏋勚佽皟璇曞拰鍒嗘瀽绛夊姛鑳姐傚畠鍏锋湁鍑鸿壊镄勬櫤鑳芥彁绀哄拰浠g爜瀹屾垚锷熻兘锛岃兘澶熸彁鍗囩紪镰佹晥鐜囥侷ntelliJ IDEA杩橀泦鎴愪简璁稿氱幇浠e寲寮鍙戝伐鍏凤纴濡傜増链鎺у埗鍜屾祴璇曟嗘灦锛屼娇寰楀畠鎴愪负涓娆鹃潪甯稿叏闱㈢殑Java缂栬疟鍣ㄣ
GCC锛圙NU Compiler Collection锛夋槸涓娆惧箍娉涗娇鐢ㄧ殑寮婧怌/C++缂栬疟鍣锛屾敮鎸佸氱嶅钩鍙板拰镎崭綔绯荤粺銆侴CC鍏锋湁浼樼镄勪紭鍖栧姛鑳藉拰涓板瘜镄勮瘖鏂淇℃伅锛岃兘澶熷府锷╁紑鍙戣呮彁鍗囦唬镰佹ц兘骞跺畾浣嶉梾棰樸傛ゅ栵纴GCC杩樻敮鎸佽稿氭墿灞曞拰璇瑷鐗规э纴浣垮缑瀹冩垚涓篊/C++寮鍙戣呯殑棣栭夌紪璇戝櫒銆
Clang鏄涓娆剧幇浠e寲镄凛/C++缂栬疟鍣锛屼互鍏跺嚭镩茬殑镐ц兘鍜岄敊璇璇婃柇鑳藉姏钥岄椈钖嶃侰lang鍏锋湁蹇阃熺殑缂栬疟阃熷害鍜岀簿纭镄勯敊璇鎻愮ず锛岃兘澶熸彁鍗囧紑鍙戞晥鐜囥傛ゅ栵纴Clang杩樻敮鎸佽稿氩厛杩涚殑璇瑷鐗规у拰宸ュ叿阈撅纴浣垮缑瀹冩垚涓篊/C++寮鍙戣呯殑鍙︿竴涓浼樼阃夋嫨銆
缁间笂镓杩帮纴阍埚笿ava鍜孋/C++缂栬疟鍣ㄦ帹钻愶纴鎴戝垎鍒鎺ㄨ崘浜咵clipse鍜孖ntelliJ IDEA浠ュ强GCC鍜孋lang銆傝繖浜涚紪璇戝櫒鍦ㄤ笉钖岀殑鏂归溃閮藉叿链変紭绉镄勮〃鐜板拰鐗圭偣锛岃兘澶熸牴鎹寮鍙戣呯殑闇姹傚拰锅忓ソ杩涜岄夋嫨銆
‘陆’ 哪种计算机语言的执行速度最快、哪种最慢为什么
针对性调优过的汇编速度是最快的。所有的语言最终都到汇磨旅编 汇编再到机器语言。 语言编译的时候都有优化,所以好的汇编是最快的。但是差的汇编也不少MSP430上的程序都有一个判断执行15秒的。
程序设计语言中汇编语言速度最快,c语言效率最高,执行效率高。程序设计语言(ProgrammingLanguage):是一组用来定义计算机程序的语法规则。它是一种被标准化的交流技巧,用来向计算机发出指令。
一种计算机语言让程序员能够准确地定义计算机所需要使用的数据,并精确地定义在不同情况下所应当采取的行动。程序设计语言特点不同,适用领域也不同。
(6)c编译速度优化扩展阅读:
如今通用的编程语言有两种形式:汇编语言和高级语言。汇编语言和机器语言实质是相同的,都是直接对硬巧游告件操作,只不过指令采用了英文缩写的标识符,容易识别和记忆。源程序经汇编生成的可执行文件不仅比较小,而且执行速度很快。
高级语言是绝大多数编程者的选择。和汇编语言相比,它不但将许多相关的机器指令合成为单条指令,并且去掉了与具体操作有关但与完成工作无关的细节,例如使用堆栈、寄存器等,这样就大大简化了程序中的指令。同时,由于省略了很多细节,编程者也就不需要有太多的专业知识。
参孝明考资料来源:网络-计算机语言