Smarty3的性能问题
前篇文章中主要介绍了使用smarty3下的开发规范以及从smarty2迁移到smarty3中要注意的问题。
虽然刚出来的时候官方对性能这块给出的结果是smarty3的性能相比smarty2要好很多,但最近在实际项目使用中发现了性能方面是有很大问题的。下面通过一个具体的实例案例分析。
实际案例
由于之前使用的是smarty2,最近在向smarty3迁移的过程中,一些不重要的页面上线后运行的一直很良好。在迁移最后的一个模块后(访问量很大),上线后直接导致页面挂了,并且CPU的占有率始终是100%,只好回滚了。但在线下并不能复现挂了的情况,后来定位到可能是性能的问题,相关的QA同学进行压力测试时,证明了这一猜测。在并发量很高的情况下,线下也能复线CPU占用100%,页面挂了的情况。
事后对这个模块进行了详细的分析,以及和smarty2的对比,下面是具体的对比结果。
上图的数据是个导致页面挂了的极端情况,虽然其他页面数据上反差不会这么大,但确实反应了Smarty3有性能问题。
具体分析
从上面的图表中,使用smarty2开发的文件大小为34K。由于Smarty3里使用了模版继承(inc_layout.html 1.8K)和自定义函数(inc_util.html 25K),并且自定义函数是整个模块的,所以Smarty3的开发文件大小相对要比Smarty2大一些。
但编译后Smarty2的文件大小只有52K,Smarty3编译后确有200,我们看下到底是哪些东西导致了Smarty3编译后有那么大。
这是编译后文件依赖的代码片段,其中用了200行的代码维护了文件依赖。
只是自定义函数参数的管理代码片段,用了370行的代码进行了自定义函数参数的维护。
这时自定义函数实体的代码片段,用了1000行的代码进行自定义函数实体的维护。
还有大量使用了__set,__get等魔术方法,这些直接导致文件体积很大的原因。
性能损耗点
通过以上分析,可以大致确定影响性能有一下几个方面:
1、文件依赖管理
2、自定义函数参数管理
3、自定义函数实体代码管理(直接编译成php函数,太二了。不过跨模块的方式貌似也没其他比较好的办法)
4、过量使用了类、__set、__get等魔术方法
如何优化
既然smarty3有这么严重的性能问题,如果使用的话就要对它进行优化。下面介绍一些优化方法,主要是开发 的时候还是用smarty3的那些优秀特性,这样可以大大提高开发效率和维护成本。在代码上线之前进行编译,将影响性能的那些方式优化系统原生的方式,如:
1、优化文件依赖。如果引用本模块的文件,可以直接读取文件内容替换过去,减少文件依赖和IO开销。
2、自定义函数。如果是本模块的自定义函数并且其他模块不会引用(非通用模块一般都不会被其他模块引用),可以直接将自定义函数的主题替换过去,减少自定义函数参数管理和编译成PHP函数。
3、优化一些魔术方法,将一些魔术方式直接编译后数据的调用。
4、可以考虑在编译的时候把文件编译好,对编译后的文件将进行优化。
近期会进行smarty3优化的开发,开发完成后会细谈优化这块。