之前,FXXX 的主要开发者 L 兄曾经在 phpchina 上同我做过一些讨论。当然讨论的结果似乎不能令人满意。FXXX 对于我一直所诟病的数据库支持对于 L 兄来说似乎不是什么大的问题。而 Zend Framework 对于他来说似乎也是一直拥有效率黑洞,以及大而不精等诸多糟粕。Zend Framework 即将成为 PEAR2 是 L 兄一个比较精辟的形容。
项目中最初推翻 FXXX 转而使用 Zend Framework 主要是由于 Orcale 的支持问题。但是这个问题似乎是 FXXX 的软肋,不能碰,一碰就招致狂风暴雨般的质问。当然,质问的内容不是框架的数据库支持。而是触碰这个软肋的人的技术水平问题。而 Zend Framework 的性能黑洞,也让我带着意思疑虑。Zend Framework 的性能是否真的不可调和,这个框架是否真的又臃肿,又庞大?带着这个问题,我做了以下试验:
试验内容:为了检测 Zend Framework 的性能到底如何,我必须选择一个参照对象。很遗憾,优秀的 FXXX 被选中了。因为这个性能的疑虑正是 L 兄带给我的,所以………….解铃还需系铃人。
那么对两个框架所有的部分都进行测试,似乎不太可能。这绝对是超出我能力范围的。那么我选择了 Loader 作为测试的内容。两个框架都有各自的加载类的方法。而这个方法又是在所有使用框架的开发中需要使用的。
Zend_Loader::loadClass() vs FXXX::loadClass()
我首先在Doc Root 目录中创建了 Zend 和 FXXX 目录,用于存放两个框架必要的文件。既然是测试 Loader 那么只要存放必要的 Loader 文件就可以了。顺便可以测试一下两个框架的耦合度。
第一回合,耦合度:
Zend Framework 的耦合度低得超出了我的想象,完成这个测试只需要两个文件:Zend/Loader.php 和 Zend/Exception.php。也就是说完全可以在其他项目中按照 Zend Framework 的类命名方式来使用 Zend_Loader。比如 FXXX 的类命名规则跟 Zend Framework 也是一样的。
FXXX 的表现让我有些遗憾,并没有像口碑传颂的那样有非常低的耦合度。实际上,我在删减的过程中发现,FXXX.php 这个主文件除了同 Exception 目录中的几乎所有的异常类相关外。还同 Config 目录下的配置类相关。同时还有一个为了保正持兼容产生的 Compatibility.php 文件。也就是说如果我在一个 Zend Framework 的项目中认为 FXXX 的 loadClass 非常好,希望使用的话,除非对 FXXX.php 进行比较大的改造否则是无法很干净的使用的。
第二回合,加载的性能:
为了测试加载的性能,肯定要有许多的类来加载。这两个loadClass 本身都有是否已经加载的判断。所以无法用相同的类来在同一脚本中测试。于是我编写了如下脚本生成了 2000 个类。
<?php
$c = <<<EOT
<?php
class %s_Foo_Bar_C%d
{
function %s_Foo_Bar_C%d()
{
echo 'Hello, I`m ' . __CLASS__;
}
}
EOT;
for($i = 0; $i < 1000; $i ++)
{
file_put_contents("Zend/Foo/Bar/C$i.php", sprintf($c, 'Zend', $i, 'Zend', $i));
}
for($i = 0; $i < 1000; $i ++)
{
file_put_contents("FXXX/Foo/Bar/C$i.php", sprintf($c, 'FXXX', $i, 'FXXX', $i));
}
?>
执行后,会分别在 Zend/Foo/Bar 和 FXXX/Foo/Bar 目录下生成 1000 个类。
然后执行如下代码:
<?php
$t1 = microtime(true);
include("FXXX/FXXX.php");
for($i = 0; $i < 500; $i ++)
{
FLEA::loadClass("FXXX_Foo_Bar_C$i");
}
$t2 = microtime(true);
$F = $t2 - $t1;
$t1 = microtime(true);
include("Zend/Loader.php");
for($i = 0; $i < 500; $i ++)
{
Zend_Loader::loadClass("Zend_Foo_Bar_C$i");
}
$t2 = microtime(true);
$Z = $t2 - $t1;
$colorF = $F > $Z ? 'GREEN' : 'RED';
$colorZ = $F > $Z ? 'RED' : 'GREEN';
echo "<div style='color:$colorF'>FXXX: $F</div>";
echo "<div style='color:$colorZ'>Zend: $Z</div>";
$l = fopen('performance.htm', 'a');
fwrite($l, "<div style='color:$colorF'>FXXX: $F</div>");
fwrite($l, "<div style='color:$colorZ'>Zend: $Z</div>");
fclose($l);
?>
执行结果如下:
当然,如果对 FXXX.php 文件进行删减应该可以获得不少性能的提升。不过这违背了这个测试的初衷,不是么?
需要补充的是,Zend Framework 自己曾经有过一个 Zend.php。出于某种原因,这个文件被拆分到了若干个文件中去。详细的内容,请大家看 Zend Framework SVN中 2007-3-9 的 3834 版本的注释。
这次测试,我对 Zend Framework 的 Loader 部分相当满意,它提供了相当好的使用效率和执行效率的平衡点,关于这部分的一些纤细分析,请看
Zend Framework 代码分析——Zend_Loader
对于 FXXX 来说,这个测试所表现出来的内容,虽然并没有我所预期的那样好。但是它依然不失为一个非常优秀的框架。如果能够进一步降低 FXXX.php 文件耦合度,真正实现 L 兄所描述的“在灵活性方面,FxxxPHP 和 ZF 根本就是一个层次的”以及“都是极小的核心 + 可选的扩展功能”,那应该会有更大的飞跃。呵呵~~呵呵呵呵~~希望我说这样的话不会再次让 L 兄觉得恼火又给我扣上一顶"侮辱了所有为解决企业应用面对的困难做出努力的人们"的高帽子。
谢谢大家,谢谢CCTV,谢谢MTC,谢谢所有看过本文,并且谴责本人的所有同僚,谢谢大家。
Leave a Reply