【实战经验话题】 在项目里,你遇过的那些性能瓶颈与解决方案(近期感慨+搜集)。

qq120848369 2013-02-04 05:28:16
加精

学生党因为没有工作经验的原因,真正进入工作并接受项目,会发现理论知识不够用了,很多问题是自己根本没碰过或者完全不知道的,尤其凸显为对计算机,操作系统,硬件,程序的基础概念缺失或者不能实际应用。
这一点在程序性能方面尤为突出,举个例子: 论坛里很多同学, 平时看书学会了STL觉得很碉堡,实际上STL只是一个通用的高效解决方案而已,真实的项目往往因为STL而拖了后腿,因为不同的业务可以做出针对性的优化,而不是一个STL万岁。
说STL可能大家没有实际体会,因为你并不一定质疑过它。 近两天在论坛里看到过这样的帖子, 大致就是想问:“多线程写磁盘怎么样才快?”。 以前的我可能认为,多线程肯定比单线程快, 也会怀疑多线程寻道会很繁忙会不会不太好, 学习认真的同学还会知道4KB写磁盘是速度最快的理论值, 但自己仍然是拿不准主意的,因为从来没有经历过,除非你做过试验。

发这个贴,一方面要告诉大家,尤其是还没有参与到工作中或者工作还没起步的同学,注意开发基本功的积累与尝试,注意对操作系统,硬件,程序三者在性能方面的关系,积极的探索与实验。 另一方面,也希望有类似经验的同学跟帖,互相学习,因为实战经验是很重要的,提前接触过可以避免踩坑。

什么是好程序? 能够通过把硬件性能榨干以便提升程序自身性能的程序才是好程序。
...全文
12838 173 打赏 收藏 转发到动态 举报
写回复
用AI写文章
173 条回复
切换为时间正序
请发表友善的回复…
发表回复
庄鱼 2013-04-12
  • 打赏
  • 举报
回复
有关函数的结构类型参数使用引用与指针问题,一个不为人知的性能问题:指针参数运用比引用参数运用效率要高,但单读写上,引用要比指针方便而且没有所谓的创建、回收指针的“副作用”(事实上在内存中个更容易产生内存碎片,尤其是当存在临时中间变量对该引用进行临时标注时,将引发类型的复制,这比使用指针要低效得多)。因此,复杂类型变量建议用指针代替引用,但简单类型建议用引用代替指针。
孔方兄_ 2013-04-10
  • 打赏
  • 举报
回复
能够通过把硬件性能榨干以便提升程序自身性能的程序才是好程序。 灰常赞同这句话
turing-complete 2013-04-09
  • 打赏
  • 举报
回复
引用 5 楼 qq120848369 的回复:
分享一个经验: malloc/new分配大块内存(比如1M),会变得很慢,要相信它真的很慢,为什么呢? 因为malloc大块内存会引发mmap引起严重缺页,进程会进入不可中断状态(D状态)导致程序完全不响应。 对于此类需求,应该预分配内存池或者做对象回收链表解决。
可以尝试一下tcmalloc 和 jemalloc,号称“零开发代价带来10%的性能提升”
regainworld 2013-04-09
  • 打赏
  • 举报
回复
楼上给出的那个网址看了,很全面到位 工作中遇到的,开发一个数据处理程序,用Intel Vtune查找性能瓶颈,发现大部分时间都在sprintf上,接着查各种快速格式化方法,找到一个modp,提高浮点数转字符串的效率;搜到一个打印char的快速方法,很简单: char str[3]; char x; str[0] = "0123456789abcdef"[x>>4]; str[1] = "0123456789abcdef"[x&0x0f]; str[2] = '\0'; 效率大幅度提高,接下来的瓶颈就是楼上很多人提到的new/delete了,不过已经满足项目要求,没再做优化 体会:优化代码最关键的是找准最影响性能的部分
绿 2013-04-08
  • 打赏
  • 举报
回复
CSDN可不可以提供换肤功能。晚上略刺眼。。
芝麻开门IT 2013-04-08
  • 打赏
  • 举报
回复
学到了,mark一下,谢谢楼主分享~~
qq120848369 2013-04-03
  • 打赏
  • 举报
回复
引用 186 楼 kilior 的回复:
引用 172 楼 xiaomili0929 的回复:深有同感。我的体会: 1、程序出了问题,在问题解决之前,始终坚信“代码有问题,只是我不知道在哪儿”的观点很重要。 2、不容易重现的问题,往往是确定问题代码很难,修改问题代码很简单。 3、在别人的代码里找问题比在自己的代码里找问题一般会更有耐心。 4、缩小嫌疑代码范围很重要,这需要“感觉”。 5、“感觉”是靠观点……
千万不要忽视编译器警告, 一个size_t *的函数参数, 结果传了一个int的地址进去,在64位平台上size_t通常是8字节,导致函数内存写越界。
kilior 2013-04-03
  • 打赏
  • 举报
回复
引用 172 楼 xiaomili0929 的回复:
深有同感。我的体会: 1、程序出了问题,在问题解决之前,始终坚信“代码有问题,只是我不知道在哪儿”的观点很重要。 2、不容易重现的问题,往往是确定问题代码很难,修改问题代码很简单。 3、在别人的代码里找问题比在自己的代码里找问题一般会更有耐心。 4、缩小嫌疑代码范围很重要,这需要“感觉”。 5、“感觉”是靠观点、细心、耐心、思维等锻炼出来的。 引用 171 楼 wang87325 ……
同感,解决过一个不可重现问题。 就是有人无聊做pclint告警清零,把一个变量类型从无符号改为整数。 导致边界值判断失效,只有多次操作才会重现,,,, 4个人花了3天检视超过10000行代码。。。。
赵4老师 2013-03-07
  • 打赏
  • 举报
回复
检查是否资源泄漏的办法之一: 在任务管理器 进程 查看 选择列 里面选择:内存使用、虚拟内存大小、句柄数、线程数、USER对象、GDI对象 让你的程序(进程)不退出,循环执行主流程很多遍,越多越好,比如1000000次甚至无限循环,记录以上各数值,再隔至少一小时,越长越好,比如一个月,再记录以上各数值。如果以上两组数值的差较大或随时间流逝不断增加,则铁定有对应资源的资源泄漏! 使用电脑计时有时误差会很大,因为待测程序段的运行会影响电脑时钟。 将待测程序段循环足够多次,手动掐秒表计时可能更准确。
赵4老师 2013-03-07
  • 打赏
  • 举报
回复
程序员要做的不是尽力避免错误,而是聚焦在快速发现并改正错误。真正以快速方式轻易解决错误,“快速的失败”远胜过“预防错误”。Fred George
ryfdizuo 2013-03-07
  • 打赏
  • 举报
回复
公司最讲究输出,尤其对于初入职场的人,性能优化之前要让别人信服这么搞一定会有良性的输出。性能优化前后一定要有一个量化的对比数据。当然对于一些通用的优化思路,结果大家都是认可的也就不要强调了,想到几点: 1. 缓存 两个关键点:LRU淘汰机制,HASH查找。 一般是LRU,MRU很少吧? 2. 预取 预取配合缓存使用,在使用之前将数据准备好,减少访问延迟。 举个简单例子:IO线程和渲染线程,IO线程准备好当前帧数据时 发起requestRender请求的同时 IO线程预取下一帧的数据。 3. 批处理思想 举几个例子: a)磁盘IO,以大数据块为单位。 b)调用opengl/opengles 绘制时,数据上传给GPU需要CPU参与,数据批量上传能够减少GPU等待,提高绘制性能,可以测试一下1w次绘制,每次绘制1个线条;和一次绘制,每次绘制1w个线条。性能不可同日而语。opengl相关的优化 tips还很多~ 4. 数据压缩 任何网络IO的数据都建议压缩,尤其移动开发中。采用通用的zlib库压缩结果不一定最佳,最优方式:根据数据分布的规律,设计专用的压缩算法。 PS:数据压缩有点偏题了,属于数据量优化范畴。
qq120848369 2013-03-02
  • 打赏
  • 举报
回复
引用 179 楼 FreeFice 的回复:
使用C/C++工作多年,感觉最大的并不是程序代码上面的问题,说实在,现在的编译器都已经很聪明,简单的代码问题及性能问题其都能够做到事先提示、编译优化,但真正影响项目稳定与效率的通常都是业务逻辑、框架结构等问题,而这些很多都跟需求分析不彻底、框架设计不完全有关(有的甚至没有框架设计,上来直接写代码,事后补设计文档,这样的代码效率怎么保证)。我觉得编程的人要学会不坐在电脑跟前……
嗯, 说的好.
庄鱼 2013-03-01
  • 打赏
  • 举报
回复
使用C/C++工作多年,感觉最大的并不是程序代码上面的问题,说实在,现在的编译器都已经很聪明,简单的代码问题及性能问题其都能够做到事先提示、编译优化,但真正影响项目稳定与效率的通常都是业务逻辑、框架结构等问题,而这些很多都跟需求分析不彻底、框架设计不完全有关(有的甚至没有框架设计,上来直接写代码,事后补设计文档,这样的代码效率怎么保证)。我觉得编程的人要学会不坐在电脑跟前写代码,通过纸上分析的方式,真正清晰明了自己在做什么,这样才能保证编写出来的代码是安全可靠的。
qingcairousi 2013-02-25
  • 打赏
  • 举报
回复
I/O永远是瓶颈,而且永远是在意想不到的地方出现瓶颈。 比如os x上面,一口气读入本地硬盘的一个大文件不会导致同一个硬盘其他I/O出现瓶颈,但是对移动硬盘上面的同样操作就会导致很严重的瓶颈。 因此应当尽可能地使用异步I/O。 我做得比较多的是提高程序响应的工作,所以比较倾向于用各种异步操作来把计算密集型、io密集型的任务切分为尽可能小的异步任务,以期能够在任何时候都能够实现任务调度,以达成“高响应”的目的。
疯狂的红豆 2013-02-24
  • 打赏
  • 举报
回复
看了一半 后面的再看吧。
szqh97 2013-02-23
  • 打赏
  • 举报
回复
GOOD,mark
xiaomili0929 2013-02-22
  • 打赏
  • 举报
回复
深有同感。我的体会: 1、程序出了问题,在问题解决之前,始终坚信“代码有问题,只是我不知道在哪儿”的观点很重要。 2、不容易重现的问题,往往是确定问题代码很难,修改问题代码很简单。 3、在别人的代码里找问题比在自己的代码里找问题一般会更有耐心。 4、缩小嫌疑代码范围很重要,这需要“感觉”。 5、“感觉”是靠观点、细心、耐心、思维等锻炼出来的。
引用 171 楼 wang87325 的回复:
我也来抛砖引玉吧,说一下我在一个大型项目中的经验。 这个项目是一个电信行业相关的,分为3个模块,首先A和B模块交互多次,然后将结果给C模块计算。 项目上线后,每天总有千万分之一的概率出现一些错误,几千万条数据中总有几条错的,由于各个模块分工明确,各组都排查了说没问题,这种问题概率很低,肯定是某种特殊的情况才出现,一般肯定排查不出来。 各组一起开会分析几次,都没找到问……
2008-horse 2013-02-22
  • 打赏
  • 举报
回复
先收藏,备用
qq120848369 2013-02-22
  • 打赏
  • 举报
回复
引用 172 楼 xiaomili0929 的回复:
深有同感。我的体会: 1、程序出了问题,在问题解决之前,始终坚信“代码有问题,只是我不知道在哪儿”的观点很重要。 2、不容易重现的问题,往往是确定问题代码很难,修改问题代码很简单。 3、在别人的代码里找问题比在自己的代码里找问题一般会更有耐心。 4、缩小嫌疑代码范围很重要,这需要“感觉”。 5、“感觉”是靠观点、细心、耐心、思维等锻炼出来的。 引用 171……
嗯, 心态需要慢慢调整, 找自己的bug容易受思维影响, 需要锻炼跳脱出去的办法.
qq120848369 2013-02-22
  • 打赏
  • 举报
回复
引用 171 楼 wang87325 的回复:
我也来抛砖引玉吧,说一下我在一个大型项目中的经验。 这个项目是一个电信行业相关的,分为3个模块,首先A和B模块交互多次,然后将结果给C模块计算。 项目上线后,每天总有千万分之一的概率出现一些错误,几千万条数据中总有几条错的,由于各个模块分工明确,各组都排查了说没问题,这种问题概率很低,肯定是某种特殊的情况才出现,一般肯定排查不出来。 各组一起开会分析几次,都没找到问……
嗯, 说的好, 有问题就能解决, 要坚持不懈.
加载更多回复(153)

64,646

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧