ZendFramework官方提供的性能优化没有实际意义
来源:互联网 发布:淘宝网小衫女 编辑:程序博客网 时间:2024/06/06 06:24
昨天把zf的官方性能优化都做了一遍,本来希望官方的性能优化方案能够真正起到优化效果,中间由于bug误以为有效果了,还发了一篇博文,可惜后来一查完全越优化越差了。下面简单吧ZF官方的性能优化说一下,还有最新的(ZF1版,第二版还没有怎么用)ZF1.12中添加的autoload_classmap的机制,设计cache的部分就不提了,那个减少了代码的执行逻辑,性能提升是肯定的(还需要对比缓存获取过程和减少的代码逻辑执行的时间差,提升不绝对)。
官方优化如下:
1、在include_path的路径中使用绝对路径,这样可以使用php的realpath cache
While this may seem a micro-optimization, the fact is that if you don't, you'll get very little benefit from PHP's realpath cache, and as a result, opcode caching will not perform nearly as you may expect.2、减少include_path的路径定义,定义ZF在include_path的前面,将当前目录放在最后或者不使用当前目录,这样可以加快文件查找的速度。
Include paths are scanned in the order in which they appear in the include_path. Obviously, this means that you'll get a result faster if the file is found on the first scan rather than the last. Thus, a rather obvious enhancement is to simply reduce the number of paths in your include_path to only what you need. Look through each include_path you've defined, and determine if you actually have any functionality in that path that is used in your application; if not, remove it.
目的是为了加快文件查找过程,觉得这点不够好,最好是所有文件都使用绝对地址加载不要查找,浪费这个时间做什么啊
3、减少不需要的require_once,完全使用autoload和require加载,官方提供了一个shell来删除require_once
- % cd path/to/ZendFramework/library
- % find . -name '*.php' -not -wholename '*/Loader/Autoloader.php' \
- -not -wholename '*/Application.php' -print0 | \
- xargs -0 sed --regexp-extended --in-place 's/(require_once)/\/\/ \1/g'
另外,最好都使用require或include,不要加once,原因看http://www.laruence.com/2012/09/12/2765.html;
使用apc的用户,在产品上线后可以把apc的stat设置为0,不让它检查文件修改,这样也可以获得性能提升,更新文件可以自己写程序清理下缓存
4、加快插件加载,使用一个include文件将常用插件放在文件中
个人感觉这个行为的过程就是把每次单独加载的过程改成一次完成,然后依靠apc等缓存来提速,这个的作用真不明显5、使用自动加载器Zend_Loader_ClassMapAutoloader
这个确实没有怎么感觉到提升,个人认为即使加了这个也不能解决ZF过于臃肿的问题,优化本身就有限制。
这里给个添加的方法,有兴趣的朋友可以试试,以下部分内容来自上次误写的一篇博文。
加载器的使用:
在ZF1.12的目录中有一个bin目录下面有加载器类需要的classmap文件创建程序classmap_generator.php,通过这个创建器我们可以对相应目录下的类进行classmap文件生成,生成文件默认是在指定的class目录下的,也就是说都是基于你给创建器指定的目录的,也可以通过-o or --output 来指定。
在进行生成classmap生成前最好看下创建器的帮助,使用php classmap_generator.php -h,打印有如下信息:
Usage: classmap_generator.php [ options ]
--help|-h Get usage message
--library|-l [ <string> ] Library to parse; if none provided, assumes current directory
--output|-o [ <string> ] Where to write autoload file; if not provided, assumes "autoload_classmap.php" in library directory
--overwrite|-w Whether or not to overwrite existing autoload file
--help|-h Get usage message
--library|-l [ <string> ] Library to parse; if none provided, assumes current directory
--output|-o [ <string> ] Where to write autoload file; if not provided, assumes "autoload_classmap.php" in library directory
--overwrite|-w Whether or not to overwrite existing autoload file
然后就可以使用,例如:php classmap_generator.php -l /data/www/library, 执行完就可以看到映射文件了。
接下来就要使用加载器了,可以看到Zend_Loader_ClassMapAutoloader文件里面提供了register,autoload方法,通过这个方法可以直接使用加载器,提醒,这里需要一个前提,如果你先前没有使用其他加载器,这里可以直接使用,如果先前有使用,比如我自己就一直使用Zend_Loader_Autoloader,并注册了一些命名空间,这样使用的时候就会有问题,如果映射文件包含所有加载的类,可以去掉原来的加载器直接使用,如果不是这样,保险起见可以把类映射加载器作为Zend_Loader_Autoloader的一个回调就好了,如下:
require_once LIB_DIR . 'Zend/Loader/ClassMapAutoloader.php';
$loader_map = new Zend_Loader_ClassMapAutoloader();
$loader_map->registerAutoloadMaps( array(LIB_DIR . 'autoload_classmap.php' , APP_DIR . 'models' . DIRECTORY_SEPARATOR . 'autoload_classmap.php' ));
require_once LIB_DIR . 'Zend/Loader/Autoloader.php';
$loader = Zend_Loader_Autoloader::getInstance();
$loader->unshiftAutoloader(array($loader_map, 'autoload' ));
然后把注册的命名空间去掉,就可以使用了。
硬件环境
CPU: Intel(R) Xeon(R) CPU E5620
mem: 4G used 2.4 free 1.3
软件环境
nginx 1.2.4 php 5.3.17
不使用类加载器:
Concurrency Level: 40
Time taken for tests: 0.811 seconds
Complete requests: 100
Failed requests: 0
Write errors: 0
Total transferred: 449700 bytes
HTML transferred: 437600 bytes
Requests per second: 123.29 [#/sec] (mean)
Time per request: 324.432 [ms] (mean)
Time per request: 8.111 [ms] (mean, across all concurrent requests)
Transfer rate: 541.45 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 2 1.4 2 14
Processing: 47 253 81.3 280 343
Waiting: 44 253 81.4 280 343
Total: 48 255 81.2 282 344
Percentage of the requests served within a certain time (ms)
50% 282
66% 292
75% 308
80% 318
90% 333
95% 336
98% 344
99% 344
100% 344 (longest request)
Time taken for tests: 0.811 seconds
Complete requests: 100
Failed requests: 0
Write errors: 0
Total transferred: 449700 bytes
HTML transferred: 437600 bytes
Requests per second: 123.29 [#/sec] (mean)
Time per request: 324.432 [ms] (mean)
Time per request: 8.111 [ms] (mean, across all concurrent requests)
Transfer rate: 541.45 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 2 1.4 2 14
Processing: 47 253 81.3 280 343
Waiting: 44 253 81.4 280 343
Total: 48 255 81.2 282 344
Percentage of the requests served within a certain time (ms)
50% 282
66% 292
75% 308
80% 318
90% 333
95% 336
98% 344
99% 344
100% 344 (longest request)
使用大文件(72K)同时使用类加载器:
Concurrency Level: 40
Time taken for tests: 0.831 seconds
Complete requests: 100
Failed requests: 0
Write errors: 0
Total transferred: 449700 bytes
HTML transferred: 437600 bytes
Requests per second: 120.32 [#/sec] (mean)
Time per request: 332.433 [ms] (mean)
Time per request: 8.311 [ms] (mean, across all concurrent requests)
Transfer rate: 528.42 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 1 1.5 1 15
Processing: 46 258 79.0 300 334
Waiting: 45 258 79.0 299 334
Total: 48 260 78.9 301 335
Percentage of the requests served within a certain time (ms)
50% 301
66% 307
75% 311
80% 313
90% 314
95% 322
98% 330
99% 335
100% 335 (longest request)
Time taken for tests: 0.831 seconds
Complete requests: 100
Failed requests: 0
Write errors: 0
Total transferred: 449700 bytes
HTML transferred: 437600 bytes
Requests per second: 120.32 [#/sec] (mean)
Time per request: 332.433 [ms] (mean)
Time per request: 8.311 [ms] (mean, across all concurrent requests)
Transfer rate: 528.42 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 1 1.5 1 15
Processing: 46 258 79.0 300 334
Waiting: 45 258 79.0 299 334
Total: 48 260 78.9 301 335
Percentage of the requests served within a certain time (ms)
50% 301
66% 307
75% 311
80% 313
90% 314
95% 322
98% 330
99% 335
100% 335 (longest request)
可以看到和原来情况差不多,究其原因,个人通过跟踪php-fpm的进程过程,发现文件本身的加载在ZF中已经达到160个文件以上了,这个classmap不能减少这个操作,只能说是应用了官方优化的第一条,这个不能解决框架本身的性能瓶颈。对比下yii包含的文件数60个,这个就是性能差距的根本。
资料:
http://talks.php.net/show/froscon08/0
http://framework.zend.com/manual/1.12/en/performance.html
http://yiiframework.com/
- ZendFramework官方提供的性能优化没有实际意义
- BOOL WINAPI的实际意义
- android-提供布局的整体性能-优化布局层次结构
- 亿能提供的性能测试诊断分析与优化
- Elasticsearch性能优化官方建议
- MyBatis的Cache实际意义不大
- 特征值和特征向量的实际意义
- 特征值和特征向量的实际意义
- 特征值和特征向量的实际意义
- 特征值和特征向量的实际意义
- Android官方开发文档Training系列课程中文版:布局性能优化之ListView的优化
- Windows Vista性能优化官方指南
- Flash 平台应用性能优化官方文档
- Flash 平台应用性能优化官方文档
- Flash 平台应用性能优化官方文档
- Flash 平台应用性能优化官方文档
- AS3.0 性能优化官方文档
- Flash 平台应用性能优化官方文档
- android Intents和Intent Filters - 开发文档翻译 - 1
- Linux 2.6内核的设备模型
- 常用的C变量的定义方式
- 使用getGenericSuperclass()和getActualTypeArguments()将DAO做成泛型
- hibernate中实体关联的注解写法(一对多,多对一)
- ZendFramework官方提供的性能优化没有实际意义
- 第二次打豆豆
- windows xp下配置JDK环境变量(附:第一个例子程序,命令行下和eclipse下)
- LigerUi中Grid控件中的日期列的日期转换技巧(示例源代码)
- VC中MessageBox与AfxMessageBox用法与区别
- boost dynamic_bitset
- eclipse中安装插件方式(links方式)
- 数组
- 在IntelliJ IDEA环境下创建第一个Grails项目