相对C而言,写C++代码经常一不小心就会引入一些临时变量,比如函数实参、函数返回值。在临时变量之外,也会有其他一些情况会带来一些冗余的变量拷贝。
之前针对冗余的变量拷贝问题写过一些帖子,详情请点击这里。
多重过滤
很多服务都会过滤的部分结果的需求,比如游戏交谈中过滤需要过滤掉敏感词。假设现在有两个过滤词典,一个词典A内容较少,另一个词典B内容较多,现在有1000个词需要验证合法性。
词落在词典A中的概率是1%,落在词典B中的概率是10%,而判断词是否落在词典A或B中的 *** 作耗时差不多,记作N。
那么要判断词是否合法,有两种方式:
1. 先判断词是否在A中,如果在返回非法;如果不在再判断是否在B中,如果在返回非法,否则返回合法。
2. 和方式一类似,不过是先判断是否在B中。
现在我们来计算两种方式的耗时:
1. 1000*N+1000*(1-1%)*N
2. 1000*N+1000*(1-10%)*N
很明显,方式二的过滤 *** 作排序优化方式一。
说得有些啰嗦,其实简单点说就是一句话:多重过滤中把强过滤前移;过滤强度差不多时,过滤消耗较小的前移。
如果有些过滤条件较强,但是过滤消耗也较大怎么办?该前移还是后移?个人到没遇到过这种情况,如果确实需要考虑,也可以用之前计算方式一、二整体耗时的方法也计算一遍。
字符数组的初始化
一些情况是:写代码时,很多人为了省事或者说安全起见,每次申请一段内存之后都先全部初始化为0。
另一些情况是:用了一些API,不了解底层实现,把申请的内存全部初始化为0了,比如char buf[1024]=""的方式,有篇帖子写得比较细,请看这里。
上面提到两种内存初始化为0的情况,其实有些时候并不是必须的。比如把char型数组作为string使用的时候只需要初始化第一个元素为0即可,或者把char型数组作为一个buffer使用的大部分时候根本不需要初始化。
频繁的内存申请、释放 *** 作
曾经遇到过一个性能问题是:一个服务在启动了4-5小时之后,性能突然下降。
查看系统状态发现,这时候CPU的sys态比较高,同时又发现系统的minflt值迅速增加,于是怀疑是内存的申请、释放造成的性能下降。
最后定位到是服务的处理线程中,在处理请求时有大量申请和释放内存的 *** 作。定位到原因之后就好办了,直接把临时申请的内存改为线程变量,性能一下子回升了。
能够迅速的怀疑到是临时的内存申请造成的性能下降,还亏之前看过这篇帖子。
至于为什么是4-5小时之后,性能突然下降,则怀疑是内存碎片的问题。
提前计算
这里需要提到的有两类问题:
1. 局部的冗余计算:循环体内的计算提到循环体之前
2. 全局的冗余计算
问题1很简单,大部分人应该都接触到过。有人会问编译器不是对此有对应的优化措施么?对,公共子表达式优化是可以解决一些这个问题。不过实测发现如果循环体内是调用的某个函数,即使这个函数是没有side effect的,编译器也无法针对这种情况进行优化。(我是用gcc 3.4.5测试的,不排除更高版本的gcc或者其他编译器可以针对这种情况进行优化)
对于问题2,我遇到的情况是:服务代码中定义了一个const变量,假设叫做MAX_X,处理请求是,会计算一个pow(MAX_X)用作过滤阈值,而性能分析发现,这个pow *** 作占了整体系统CPU占用的10%左右。对于这个问题,我的优化方式很简单,直接计算定义一个MAX_X_POW变量用作过滤即可。代码修改2行,性能提升10%。
NXT优化报configuration error解决办法如下它的意思是:应用程序中的服务器错误。1.搜索文件夹,检查站点下是否多了一个web.config文件。多了的话直接删掉一个就可以
2.检查web.config里面配置的framework版本,是否和你编译所选择的版本相同。,一般就是2.0,与3.5,与4.0之间转换。
应该是应用程序中的服务器错误。遇到ConfigurationError可以这样处理,搜索文件夹检查站点下是否多了一个web、config文件,如果多了的话直接删掉一个就可以。
检查web、config里面配置的framework版本,是否和你编译所选择的版本相同。一般就是2、0与3、5与4、0之间转换,最后模式选择集成就行。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)