PHP网页编程之提拔PHP功能之改动Zend引擎分发体例
PHP和HTML混合编程应该不成问题,在这期间,你完全可以让PHP给你算算 一加一等于几,然后在浏览器输出,不要觉得幼稚,这的确是跟阿波罗登月一样,你打的是一小段代码,但是对于你的编程之路,可是迈出了一大步啊!兴奋吧?但是不得不再给你泼点冷水,您还是菜鸟一个。从PHP5.1入手下手,PHP供应了用户对Zend VM履行分发体例的选择接口.
之前的文章中, 我也提过这方面的内容, Zend虚拟机在履行的时分, 关于编译生成的op_array中的每条opline的opcode城市分发到响应的处置器(zend_vm_def.h界说)履行, 而依照分发的体例分歧, 分发进程可以分为CALL, SWITCH, 和GOTO三品种型.
默许是CALL体例, 也就是一切的opcode处置器都界说为函数, 然后虚拟机挪用. 这类体例是传统的体例, 也普通被以为是最不乱的体例.
SWITCH体例和GOTO体例则和其定名的意义不异, 分离经由过程switch和goto来分发opcode到对应的处置逻辑(段).
官方给出的描写是:
CALL – Uses function handlers for opcodes
SWITCH – Uses switch() statement for opcode dispatch
GOTO – Uses goto for opcode dispatch (threaded opcodes architecture)
GOTO is usually (depends on CPU and compiler) faster than SWITCH, which
tends to be slightly faster than CALL.
CALL is default because it doesn’t take very long to compile as opposed
to the other two and in general the speed is quite close to the others.
那末假如利用GOTO体例, 效力上究竟能进步几何呢?
明天我就分离利用各类体例来测试一番, 测试剧本bench.php.
第一点被证实的就是, 官方说的GOTO体例编译耗时明显高于其他俩种体例, 我一入手下手在虚拟机上编译, 每次都Hangup(), 最初只好换了个微弱点的物理机, 大约3分钟后, 编译胜利..
测试情况:
PHP 5.3.0 Linux
AMD Opteron(tm) Processor 270(2G) X 4 6G Memory
编译参数:
./configure --with-zend-vm=CALL/GOTO/SWITCH
测试了局以下(都是三次取中值):
CALL体例:
laruence@dev01.tc$ sapi/cli/php bench.php
simple 0.358
simplecall 0.418
simpleucall 0.405
simpleudcall 0.424
mandel 1.011
mandel2 1.238
ackermann(7) 0.375
ary(50000) 0.083
ary2(50000) 0.075
ary3(2000) 0.561
fibo(30) 1.156
hash1(50000) 0.114
hash2(500) 0.091
heapsort(20000) 0.270
matrix(20) 0.276
nestedloop(12) 0.599
sieve(30) 0.350
strcat(200000) 0.039
------------------------
Total 7.844
SWITCH体例:
laruence@dev01.tc$ sapi/cli/php bench.php
simple 0.393
simplecall 0.414
simpleucall 0.424
simpleudcall 0.445
mandel 1.007
mandel2 1.254
ackermann(7) 0.392
ary(50000) 0.084
ary2(50000) 0.073
ary3(2000) 0.593
fibo(30) 1.185
hash1(50000) 0.120
hash2(500) 0.092
heapsort(20000) 0.285
matrix(20) 0.295
nestedloop(12) 0.678
sieve(30) 0.359
strcat(200000) 0.042
------------------------
Total 8.138
GOTO体例 :
laruence@dev01.tc$ sapi/cli/php bench.php
simple 0.306
simplecall 0.373
simpleucall 0.369
simpleudcall 0.385
mandel 0.879
mandel2 1.132
ackermann(7) 0.356
ary(50000) 0.081
ary2(50000) 0.073
ary3(2000) 0.525
fibo(30) 1.043
hash1(50000) 0.111
hash2(500) 0.088
heapsort(20000) 0.247
matrix(20) 0.247
nestedloop(12) 0.519
sieve(30) 0.331
strcat(200000) 0.037
------------------------
Total 7.103
可见, GOTO体例最快, SWITCH体例最慢.和官方的描写稍有不符.
GOTO体例比其默许的CALL体例, 功能提拔仍是对照分明的.
所以, 假如你但愿让PHP发扬到机制, 改动Zend VM的分发体例, 也能够做为一个思索要素.
附:
利用GOTO体例的configure选项:
--with-zend-vm=GOTO
也能够在Zend目次下利用:
php zend_vm_gen.php --with-vm-kind=
测试剧本bench.php
/**
* PHP Perf Bench Test Script
*/
function simple() {
$a = 0;
for ($i = 0; $i < 1000000; $i++)
$a++;
$thisisanotherlongname = 0;
for ($thisisalongname = 0; $thisisalongname < 1000000; $thisisalongname++)
$thisisanotherlongname++;
}
/****/
function simplecall() {
for ($i = 0; $i < 1000000; $i++)
strlen("hallo");
}
/****/
function hallo($a) {
}
function simpleucall() {
for ($i = 0; $i < 1000000; $i++)
hallo("hallo");
}
/****/
function simpleudcall() {
for ($i = 0; $i < 1000000; $i++)
hallo2("hallo");
}
function hallo2($a) {
}
/****/
function mandel() {
$w1=50;
$h1=150;
$recen=-.45;
$imcen=0.0;
$r=0.7;
$s=0; $rec=0; $imc=0; $re=0; $im=0; $re2=0; $im2=0;
$x=0; $y=0; $w2=0; $h2=0; $color=0;
$s=2*$r/$w1;
$w2=40;
$h2=12;
for ($y=0 ; $y<=$w1; $y=$y+1) {
$imc=$s*($y-$h2)+$imcen;
for ($x=0 ; $x<=$h1; $x=$x+1) {
$rec=$s*($x-$w2)+$recen;
$re=$rec;
$im=$imc;
$color=1000;
$re2=$re*$re;
$im2=$im*$im;
while( ((($re2+$im2)<1000000) && $color>0)) {
$im=$re*$im*2+$imc;
$re=$re2-$im2+$rec;
$re2=$re*$re;
$im2=$im*$im;
$color=$color-1;
}
if ( $color==0 ) {
print "_";
} else {
print "#";
}
}
print "
";
flush();
}
}
/****/
function mandel2() {
$b = " .:,;!/>)&IH%*#";
//float r, i, z, Z, t, c, C;
for ($y=30; printf("\n"), $C = $y*0.1 - 1.5, $y--;){
for ($x=0; $c = $x*0.04 - 2, $z=0, $Z=0, $x++ < 75;){
for ($r=$c, $i=$C, $k=0; $t = $z*$z - $Z*$Z + $r, $Z = 2*$z*$Z + $i, $z=$t, $k<5000; $k++)
if ($z*$z + $Z*$Z > 500000) break;
echo $b[$k%16];
}
}
}
/****/
function Ack($m, $n){
if($m == 0) return $n+1;
if($n == 0) return Ack($m-1, 1);
return Ack($m - 1, Ack($m, ($n - 1)));
}
function ackermann($n) {
$r = Ack(3,$n);
print "Ack(3,$n): $r\n";
}
/****/
function ary($n) {
for ($i=0; $i<$n; $i++) {
$X[$i] = $i;
}
for ($i=$n-1; $i>=0; $i--) {
$Y[$i] = $X[$i];
}
$last = $n-1;
print "$Y[$last]\n";
}
/****/
function ary2($n) {
for ($i=0; $i<$n;) {
$X[$i] = $i; ++$i;
$X[$i] = $i; ++$i;
$X[$i] = $i; ++$i;
$X[$i] = $i; ++$i;
$X[$i] = $i; ++$i;
$X[$i] = $i; ++$i;
$X[$i] = $i; ++$i;
$X[$i] = $i; ++$i;
$X[$i] = $i; ++$i;
$X[$i] = $i; ++$i;
}
for ($i=$n-1; $i>=0;) {
$Y[$i] = $X[$i]; --$i;
$Y[$i] = $X[$i]; --$i;
$Y[$i] = $X[$i]; --$i;
$Y[$i] = $X[$i]; --$i;
$Y[$i] = $X[$i]; --$i;
$Y[$i] = $X[$i]; --$i;
$Y[$i] = $X[$i]; --$i;
$Y[$i] = $X[$i]; --$i;
$Y[$i] = $X[$i]; --$i;
$Y[$i] = $X[$i]; --$i;
}
$last = $n-1;
print "$Y[$last]\n";
}
/****/
function ary3($n) {
for ($i=0; $i<$n; $i++) {
$X[$i] = $i + 1;
$Y[$i] = 0;
}
for ($k=0; $k<1000; $k++) {
for ($i=$n-1; $i>=0; $i--) {
$Y[$i] += $X[$i];
}
}
$last = $n-1;
print "$Y $Y[$last]\n";
}
/****/
function fibo_r($n){
return(($n < 2) ? 1 : fibo_r($n - 2) + fibo_r($n - 1));
}
function fibo($n) {
$r = fibo_r($n);
print "$r\n";
}
/****/
function hash1($n) {
for ($i = 1; $i <= $n; $i++) {
$X = $i;
}
$c = 0;
for ($i = $n; $i > 0; $i--) {
if ($X) { $c++; }
}
print "$c\n";
}
/****/
function hash2($n) {
for ($i = 0; $i < $n; $i++) {
$hash1["foo_$i"] = $i;
$hash2["foo_$i"] = 0;
}
for ($i = $n; $i > 0; $i--) {
foreach($hash1 as $key => $value) $hash2[$key] += $value;
}
$first = "foo_0";
$last = "foo_".($n-1);
print "$hash1[$first] $hash1[$last] $hash2[$first] $hash2[$last]\n";
}
/****/
function gen_random ($n) {
global $LAST;
return( ($n * ($LAST = ($LAST * IA + IC) % IM)) / IM );
}
function heapsort_r($n, &$ra) {
$l = ($n >> 1) + 1;
$ir = $n;
while (1) {
if ($l > 1) {
$rra = $ra[--$l];
} else {
$rra = $ra[$ir];
$ra[$ir] = $ra;
if (--$ir == 1) {
$ra = $rra;
return;
}
}
$i = $l;
$j = $l << 1;
while ($j <= $ir) {
if (($j < $ir) && ($ra[$j] < $ra[$j+1])) {
$j++;
}
if ($rra < $ra[$j]) {
$ra[$i] = $ra[$j];
$j += ($i = $j);
} else {
$j = $ir + 1;
}
}
$ra[$i] = $rra;
}
}
function heapsort($N) {
global $LAST;
define("IM", 139968);
define("IA", 3877);
define("IC", 29573);
$LAST = 42;
for ($i=1; $i<=$N; $i++) {
$ary[$i] = gen_random(1);
}
heapsort_r($N, $ary);
printf("%.10f\n", $ary[$N]);
}
/****/
function mkmatrix ($rows, $cols) {
$count = 1;
$mx = array();
for ($i=0; $i<$rows; $i++) {
for ($j=0; $j<$cols; $j++) {
$mx[$i][$j] = $count++;
}
}
return($mx);
}
function mmult ($rows, $cols, $m1, $m2) {
$m3 = array();
for ($i=0; $i<$rows; $i++) {
for ($j=0; $j<$cols; $j++) {
$x = 0;
for ($k=0; $k<$cols; $k++) {
$x += $m1[$i][$k] * $m2[$k][$j];
}
$m3[$i][$j] = $x;
}
}
return($m3);
}
function matrix($n) {
$SIZE = 30;
$m1 = mkmatrix($SIZE, $SIZE);
$m2 = mkmatrix($SIZE, $SIZE);
while ($n--) {
$mm = mmult($SIZE, $SIZE, $m1, $m2);
}
print "{$mm} {$mm} {$mm} {$mm}\n";
}
/****/
function nestedloop($n) {
$x = 0;
for ($a=0; $a<$n; $a++)
for ($b=0; $b<$n; $b++)
for ($c=0; $c<$n; $c++)
for ($d=0; $d<$n; $d++)
for ($e=0; $e<$n; $e++)
for ($f=0; $f<$n; $f++)
$x++;
print "$x\n";
}
/****/
function sieve($n) {
$count = 0;
while ($n-- > 0) {
$count = 0;
$flags = range (0,8192);
for ($i=2; $i<8193; $i++) {
if ($flags[$i] > 0) {
for ($k=$i+$i; $k <= 8192; $k+=$i) {
$flags[$k] = 0;
}
$count++;
}
}
}
print "Count: $count\n";
}
/****/
function strcat($n) {
$str = "";
while ($n-- > 0) {
$str .= "hello\n";
}
$len = strlen($str);
print "$len\n";
}
/*****/
function getmicrotime()
{
$t = gettimeofday();
return ($t['sec'] + $t['usec'] / 1000000);
}
function start_test()
{
ob_start();
return getmicrotime();
}
function end_test($start, $name)
{
global $total;
$end = getmicrotime();
ob_end_clean();
$total += $end-$start;
$num = number_format($end-$start,3);
$pad = str_repeat(" ", 24-strlen($name)-strlen($num));
echo $name.$pad.$num."\n";
ob_start();
return getmicrotime();
}
function total()
{
global $total;
$pad = str_repeat("-", 24);
echo $pad."\n";
$num = number_format($total,3);
$pad = str_repeat(" ", 24-strlen("Total")-strlen($num));
echo "Total".$pad.$num."\n";
}
$t0 = $t = start_test();
simple();
$t = end_test($t, "simple");
simplecall();
$t = end_test($t, "simplecall");
simpleucall();
$t = end_test($t, "simpleucall");
simpleudcall();
$t = end_test($t, "simpleudcall");
mandel();
$t = end_test($t, "mandel");
mandel2();
$t = end_test($t, "mandel2");
ackermann(7);
$t = end_test($t, "ackermann(7)");
ary(50000);
$t = end_test($t, "ary(50000)");
ary2(50000);
$t = end_test($t, "ary2(50000)");
ary3(2000);
$t = end_test($t, "ary3(2000)");
fibo(30);
$t = end_test($t, "fibo(30)");
hash1(50000);
$t = end_test($t, "hash1(50000)");
hash2(500);
$t = end_test($t, "hash2(500)");
heapsort(20000);
$t = end_test($t, "heapsort(20000)");
matrix(20);
$t = end_test($t, "matrix(20)");
nestedloop(12);
$t = end_test($t, "nestedloop(12)");
sieve(30);
$t = end_test($t, "sieve(30)");
strcat(200000);
$t = end_test($t, "strcat(200000)");
total($t0, "Total");
?>
把例子全部敲进去试验,完成一遍以后就会有心得了,因为你会发现为啥我的程序和书上的一模一样就是结果不正确。新手学习的时候必须承认,不容易,因为我也是过来人,你会发现原来有那么多常用的语句,函数都要记。 先学习php和mysql,还有css(html语言很简单)我认为现在的效果比以前的方法好。 个人呢觉得,配wamp 最容易漏的一步就是忘了把$PHP$目录下的libmysql.dll拷贝到windows系统目录的system32目录下,还有重启apache。 使用zendstdio 写代码的的时候,把tab 的缩进设置成4个空格是很有必要的 其实没啥难的,多练习,练习写程序,真正的实践比看100遍都有用。不过要熟悉引擎 不禁又想起那些说php是草根语言的人,为什么认得差距这么大呢。 要进行开发,搭建环境是首先需要做的事,windows下面我习惯把环境那个安装在C盘下面,因为我配的环境经常出现诡异事件,什么事都没做环境有的时候就不能用啦。 如果你可以写完像留言板这样的程序,那么你可以去一些别人的代码了, 作为一个合格的coder 编码的规范是必须,命名方面我推崇“驼峰法”,另外就是自己写的代码最好要带注释,不然时间长了,就算是自己的代码估计看起来都费事,更不用说别人拉。 这些都是最基本最常用功能,我们这些菜鸟在系统学习后,可以先对这些功能深入研究。 我要在声明一下:我是个菜鸟!!我对php这门优秀的语言也是知之甚少。但是我要在这里说一下php在网站开发中最常用的几个功能: 当然这种网站的会员费就几十块钱。 其实没啥难的,多练习,练习写程序,真正的实践比看100遍都有用。不过要熟悉引擎 如果你可以写完像留言板这样的程序,那么你可以去一些别人的代码了, 装在C盘下面可以利用windows的ghost功能可以还原回来(顺便当做是重转啦),当然啦我的编译目录要放在别的盘下,不然自己的劳动成果就悲剧啦。 建数据库表的时候,int型要输入长度的,其实是个摆设的输入几位都没影响的,只要大于4就行,囧。 其实没啥难的,多练习,练习写程序,真正的实践比看100遍都有用。不过要熟悉引擎 在我安装pear包的时候老是提示,缺少某某文件,才发现 那群extension 的排列是应该有一点的顺序,而我安装的版本的排序不是正常的排序。没办法我只好把那群冒号加了上去,只留下我需要使用的扩展。 php是动态网站开发的优秀语言,在学习的时候万万不能冒进。在系统的学习前,我认为不应该只是追求实现某种效果,因为即使你复制他人的代码调试成功,实现了你所期望的效果,你也不了解其中的原理。 刚开始安装php的时候,我图了个省事,把php的扩展全都打开啦(就是把php.ini 那一片 extension 前面的冒号全去掉啦),这样自然有好处,以后不用再需要什么功能再来打开。
页:
[1]