Starting from PHP5.1, PHP provides an interface for users to select a distribution method for ZendVM execution. in my previous articles, I also mentioned this. when the Zend virtual machine is running, the opcode of each opline in the op_array generated by the compilation will be distributed to the corresponding processing... "> <LINKhref =" http://www.php100.com/
Starting from PHP5.1, PHP provides an interface for users to select the Zend VM execution distribution method.
I have mentioned this in my previous articles. when the Zend virtual machine is running, the opcode of each opline in the compiled op_array is distributed to the corresponding processor (defined by zend_vm_def.h) for execution. the distribution process can be divided into CALL, SWITCH, and GOTO.
By default, the CALL method is used, that is, all opcode processors are defined as functions and then virtual machines are called. this method is a traditional method and is generally considered the most stable method.
The SWITCH mode and the GOTO mode have the same meaning as the naming method. the opcode is distributed to the corresponding processing logic (segment) through the switch and goto methods respectively ).
The official description is as follows:
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.
How much efficiency can be improved if the GOTO method is used?
Today I will test the script ghost. php in various ways.
The first proof is that the GOTO compilation time is significantly higher than that of the other methods. at first, I compiled it on a virtual machine and Hangup (compile) each time ), finally, I had to change to a strong physical machine. after about three minutes, the compilation was successful ..
Test environment:
PHP 5.3.0 Linux
AMD Opteron (tm) Processor 270 (2G) X 4 6G Memory
Compilation parameters:
./Configure -- with-zend-vm = CALL/GOTO/SWITCH
The test results are as follows (values are obtained three times ):
CALL method:
Laruence@dev01.tc $ sapi/cli/php composer. php
Easy 0.358
Simplecall 0.418
Simplecuall 0.405
Simpleudcall 0.424
Mandel 1.011
Mantel2 1.238
Ackermann (7) 0.375
Ary (1, 50000) 0.083
Army2 (50000) 0.075
Ary3 (2000) 0.561
Fiber (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 Mode:
Laruence@dev01.tc $ sapi/cli/php composer. php
Easy 0.393
Simplecall 0.414
Simplecuall 0.424
Simpleudcall 0.445
Mandel 1.007
Mantel2 1.254
Ackermann (7) 0.392
Ary (1, 50000) 0.084
Army2 (50000) 0.073
Ary3 (2000) 0.593
Fiber (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 method:
Laruence@dev01.tc $ sapi/cli/php composer. php
Easy 0.306
Simplecall 0.373
Simplecuall 0.369
Simpleudcall 0.385
Mandel 0.879
Mantel2 1.132
Ackermann (7) 0.356
Ary (1, 50000) 0.081
Army2 (50000) 0.073
Ary3 (2000) 0.525
Fiber (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
It can be seen that the GOTO method is the fastest, and the SWITCH method is the slowest. it is slightly different from the official description.
Compared with its default CALL method, the GOTO method improves performance significantly.
Therefore, if you want to enable PHP to use the mechanism and change the Zend VM distribution method, you can also consider it as a factor.
Appendix:
Use the GOTO configure option:
-- With-zend-vm = GOTO
You can also use the following in the Zend Directory:
Php zend_vm_gen.php -- with-vm-kind = [CALL | GOTO | SWITH]
Test script example. php
/**
* PHP Perf submit Test Script
*/
Function simple (){
$ A = 0;
For ($ I = 0; I I <1000000; $ I ++)
$ A ++;
$ Thisisanotherlongname = 0;
For ($ thisisalongname = 0; $ thisisalongname <1000000; $ thisisalongname ++)
$ Thisisanotherlongname ++;
}
/****/
Function simplecall (){
For ($ I = 0; I I <1000000; $ I ++)
Strlen ("hallo ");
}
/****/
Function hallo ($ ){
}
Function simpleucall (){
For ($ I = 0; I I <1000000; $ I ++)
Hallo ("hallo ");
}
/****/
Function simpleudcall (){
For ($ I = 0; I I <1000000; $ I ++)
Hallo2 ("hallo ");
}
Function hallo2 ($ ){
}
/****/
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 [0] $ 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 [dechex ($ I)] = $ I;
}
$ C = 0;
For ($ I = $ n; $ I> 0; $ I --){
If ($ X [dechex ($ I)]) {$ 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 [1];
If (-- $ ir = 1 ){
$ Ra [1] = $ 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 [0] [0]} {$ mm [2] [3]} {$ mm [3] [2]} {$ mm [4] [4 ]} \ 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 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 ");
?>