ホームページ > php教程 > php手册 > Zend エンジンの配布方法の変更による PHP のパフォーマンスの向上

Zend エンジンの配布方法の変更による PHP のパフォーマンスの向上

WBOY
リリース: 2016-06-21 08:52:46
オリジナル
1127 人が閲覧しました

PHP5.1 以降、PHP はユーザーが Zend VM の配布方法を選択するためのインターフェースを提供します。

以前の記事でも、この点について触れましたが、Zend 仮想マシンが実行されると、コンパイルされた op_array 内の各 opline のオペコードが、さまざまな分散方法に従って、対応するプロセッサ (zend_vm_def.h 定義) に分散されて実行されます。 , 配信プロセスは、CALL、SWITCH、GOTO の 3 つのタイプに分類できます。

デフォルトは CALL メソッドです。つまり、すべてのオペコード プロセッサが関数として定義され、仮想マシンによって呼び出されます。このメソッドは従来のメソッドであり、一般に最も安定したメソッドであると考えられています。

SWITCH モードと GOTO モードは、それぞれ switch と goto を通じて対応する処理ロジック (セグメント) に分配されます。

公式の説明は次のとおりです:

CALL – オペコードの関数ハンドラーを使用します

SWITCH – オペコードのディスパッチに switch() ステートメントを使用します

GOTO – オペコードディスパッチに goto を使用します (スレッドオペコードアーキテクチャ)

GOTO は通常 (CPU とコンパイラに応じて) SWITCH より高速です。

CALL よりも若干速い傾向があります。

対照的にコンパイルにそれほど時間がかからないため、CALL がデフォルトです

他の 2 つに対して、一般的に速度は他の 2 つに非常に近いです。

では、GOTO方式を使えばどれくらい効率が上がるのでしょうか?

今日はさまざまな方法を使用してテストします。テスト スクリプト Bench.php.

証明された最初の点は、公式の GOTO コンパイル時間は、最初に仮想マシン上でコンパイルした他の 2 つの方法よりも大幅に長く、最終的には (恥ずかしいことに) に変更しなければならなかったということです。より強力な物理コンピューターを使用すると、約 3 分後にコンパイルが成功しました。

テスト環境:

PHP 5.3.0 Linux

AMD Opteron(tm) プロセッサー 270(2G) X 4 6G メモリ

コンパイルパラメータ:

./configure --with-zend-vm=CALL/GOTO/SWITCH

テスト結果は以下の通り(3回の中央値です):

CALL メソッド:

laruence@dev01.tc$ sapi/cli/php bench.php

シンプル 0.358

シンプルコール 0.418

シンプルコール 0.405

simpleudcall 0.424

マンデル 1.011

マンデル2 1.238

アッカーマン(7) 0.375

ary(50000) 0.083

ary2(50000) 0.075

ary3(2000) 0.561

フィボ(30) 1.156

ハッシュ1(50000) 0.114

ハッシュ2(500) 0.091

ヒープソート(20000) 0.270

行列(20) 0.276

ネストループ(12) 0.599

ふるい(30) 0.350

strcat(200000) 0.039

-------------------------

合計 7.844

SWITCH メソッド:

laruence@dev01.tc$ sapi/cli/php bench.php

シンプル 0.393

シンプルコール 0.414

シンプルコール 0.424

simpleudcall 0.445

マンデル 1.007

マンデル2 1.254

アッカーマン(7) 0.392

ary(50000) 0.084

ary2(50000) 0.073

ary3(2000) 0.593

フィボ(30) 1.185

ハッシュ1(50000) 0.120

ハッシュ2(500) 0.092

ヒープソート(20000) 0.285

行列(20) 0.295

ネストループ(12) 0.678

ふるい(30) 0.359

strcat(200000) 0.042

-------------------------

合計 8.138

GOTO メソッド:

laruence@dev01.tc$ sapi/cli/php bench.php

シンプル 0.306

シンプルコール 0.373

シンプルコール 0.369

simpleudcall 0.385

マンデル 0.879

マンデル2 1.132

アッカーマン(7) 0.356

ary(50000) 0.081

ary2(50000) 0.073

ary3(2000) 0.525

フィボ(30) 1.043

ハッシュ1(50000) 0.111

ハッシュ2(500) 0.088

ヒープソート(20000) 0.247

行列(20) 0.247

ネストループ(12) 0.519

ふるい(30) 0.331

strcat(200000) 0.037

-------------------------

合計7.103

GOTO メソッドが最も速く、SWITCH メソッドが最も遅いことがわかります。これは公式の説明と若干矛盾しています。

デフォルトの CALL メソッドと比較すると、GOTO メソッドのパフォーマンスの向上は明らかです。

したがって、PHP の仕組みを利用して Zend VM の配布方法を変更したい場合は、検討することもできます。

添付ファイル:

GOTO 構成オプションを使用します:

--with-zend-vm=GOTO

Zend ディレクトリでも使用できます:

php zend_vm_gen.php --with-vm-kind=[CALLGOTOSWITH]

テストスクリプトベンチ.php

/

  * PHP パフォーマンス ベンチ テスト スクリプト

  ***/

関数 simple() {

$a = 0;

for ($i = 0; $i

$a++;

$thisisanotherlongname = 0;

for ($thisisalongname = 0; $thisisalongname

$thisisanotherlongname++;

}

/****/

関数 simplecall() {

for ($i = 0; $i

strlen("ハロー");

}

/**/

関数 hello($a) {

}

関数 simpleucall() {

for ($i = 0; $i

ハロー("ハロー");

}

//

関数 simpleudcall() {

for ($i = 0; $i

Hallo2("ハロー");

}

関数 Hallo2($a) {

}

//

関数 mandel() {

$w1=50;

$h1=150;

$recen=-.45;

$imcen=0.0;

$r=0.7;

$s=0; $imc=0; $im2=0;

$x=0; $w2=0;

$s=2$r/$w1;

$w2=40;

$h2=12;

for ($y=0; $y $imc=$s($y-$h2)+$imcen;

for ($x=0; $x $rec=$s($x-$w2)+$recen;

$re=$rec;

$im=$imc;

$color=1000;

$re2=$re$re;

$im2=$im$im;

while((($re2+$im2)0)) {

$im=$re$im2+$imc;

$re=$re2-$im2+$rec;

$re2=$re$re;

$im2=$im$im;

$color=$color-1;

}

if ( $color==0 ) {

print "_";

} else {

print "#";

}

}

印刷 "

";

flash();

}

}

//

関数 mandel2() {

$b = " .:,;!/>)&IH%#";

//float r、i、z、Z、t、c、C;

for ($y=30; printf("n"), $C = $y0.1 - 1.5, $y--;){

for ($x=0; $c = $x0.04 - 2, $z=0, $Z=0, $x++ for ($r=$c, $i=$C, $k=0; $t = $z$z - $Z$Z + $r, $Z = 2$z $Z + $i、$z=$t、$k if ($z$z + $Z$Z > 500000) Break;

echo $b[$k%16];

}

}

}

//

関数 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)));

}

関数アッカーマン($n) {

$r = Ack(3,$n);

print "Ack(3,$n): $rn";

}

//

関数 ary($n) {

for ($i=0; $i $X[$i] = $i;

}

for ($i=$n-1; $i>=0; $i--) {

$Y[$i] = $X[$i];

}

$last = $n-1;

print "$Y[$last]n";

}

//

関数 ary2($n) {

for ($i=0; $i $X[$i] = $i;

$X[$i] = $i;

$X[$i] = $i;

$X[$i] = $i;

$X[$i] = $i;

$X[$i] = $i;

$X[$i] = $i;

$X[$i] = $i;

$X[$i] = $i;

$X[$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";

}

//

関数 ary3($n) {

for ($i=0; $i $X[$i] = $i + 1;

$Y[$i] = 0;

}

for ($k=0; $k

  for ($i=$n-1; $i>=0; $i--) {

  $Y[$i] += $X[$i];

  }

  }

  $last = $n-1;

  print "$Y[0] $Y[$last]n";

  }

  /****/

  関数 fibo_r($n){

  return(($n

  }

  関数 fibo($n) {

  $r = fibo_r($n);

  print "$rn";

  }

  /***/

  関数ハッシュ1($n) {

  for ($i = 1; $i

  $X[dechex($i)] = $i;

  }

  $c = 0;

  for ($i = $n; $i > 0; $i--) {

  if ($X[dechex($i)]) { $c++; }

  }

  print "$cn";

  }

  //

  関数ハッシュ2($n) {

  for ($i = 0; $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";

  }

  //

  関数 gen_random ($n) {

  グローバル $LAST;

  return( ($n ($LAST = ($LAST IA + IC) % IM)) / IM );

  }

  関数 heapsort_r($n, &$ra) {

  $l = ($n >> 1) + 1;

  $ir = $n;

  一方 (1) {

  if ($l > 1) {

  $rra = $ra[--$l];

  } else {

  $rra = $ra[$ir];

  $ra[$ir] = $ra[1];

  if (--$ir == 1) {

  $ra[1] = $rra;

  戻る;

  }

  }

  $i = $l;

  $j = $l

  while ($j

  if (($j

  $j++;

  }

  if ($rra

  $ra[$i] = $ra[$j];

  $j += ($i = $j);

  } else {

  $j = $ir + 1;

  }

  }

  $ra[$i] = $rra;

  }

  }

  関数 heapsort($N) {

  グローバル $LAST;

  定義("IM", 139968);

  定義("IA", 3877);

  定義("IC", 29573);

  $LAST = 42;

  for ($i=1; $i

  $ary[$i] = gen_random(1);

  }

  heapsort_r($N, $ary);

  printf("%.10fn", $ary[$N]);

  }

  //

  関数 mkmatrix ($rows, $cols) {

  $count = 1;

  $mx = array();

  for ($i=0; $i

  for ($j=0; $j

  $mx[$i][$j] = $count++;

  }

  }

  return($mx);

  }

  関数 mmult ($rows, $cols, $m1, $m2) {

  $m3 = 配列();

  for ($i=0; $i

  for ($j=0; $j

  $x = 0;

  for ($k=0; $k

  $x += $m1[$i][$k] $m2[$k][$j];

  }

  $m3[$i][$j] = $x;

  }

  }

  return($m3);

  }

  関数行列($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";

  }

  //

  関数nestedloop($n) {

  $x = 0;

  for ($a=0; $a

  for ($b=0; $b

  for ($c=0; $c

  for ($d=0; $d

  for ($e=0; $e

  for ($f=0; $f

  $x++;

  print "$xn";

  }

  //

  関数 sieve($n) {

  $count = 0;

  while ($n-- > 0) {

  $count = 0;

  $flags = 範囲 (0,8192);

  for ($i=2; $i

  if ($flags[$i] > 0) {

  for ($k=$i+$i; $k

  $flags[$k] = 0;

  }

  $count++;

  }

  }

  }

  print "カウント: $countn";

  }

  /***/

  関数 strcat($n) {

  $str = "";

  while ($n-- > 0) {

  $str .= "こんにちは";

  }

  $len = strlen($str);

  print "$lenn";

  }

  //

  関数 getmicrotime()

  {

  $t = gettimeofday();

  return ($t['sec'] + $t['usec'] / 1000000);

  }

  関数 start_test()

  {

  ob_start();

  return getmicrotime();

  }

  関数 end_test($start, $name)

  {

  グローバル $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();

  }

  関数 total()

  {

  グローバル $total;

  $pad = str_repeat("-", 24);

  echo $pad."n";

  $num = 数値形式($total,3);

  $pad = str_repeat(" ", 24-strlen("Total")-strlen($num));

  echo "合計".$pad.$num."n";

  }

  $t0 = $t = start_test();

  simple();

  $t = end_test($t, "シンプル");

  simplecall();

  $t = end_test($t, "simplecall");

  simpleucall();

  $t = end_test($t, "simpleucall");

  simpleudcall();

  $t = end_test($t, "simpleudcall");

  マンデル();

  $t = end_test($t, "マンデル");

  mandel2();

  $t = end_test($t, "mandel2");

  アッカーマン(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)");

  フィボ(30);

  $t = end_test($t, "fibo(30)");

  ハッシュ1(50000);

  $t = end_test($t, "hash1(50000)");

  ハッシュ2(500);

  $t = end_test($t, "hash2(500)");

  ヒープソート(20000);

  $t = end_test($t, "heapsort(20000)");

  行列(20);

  $t = end_test($t, "行列(20)");

  ネストループ(12);

  $t = end_test($t, "nestedloop(12)");

  ふるい(30);

  $t = end_test($t, "sieve(30)");

  strcat(200000);

  $t = end_test($t, "strcat(200000)");

  total($t0, "合計");

  ?>



関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のおすすめ
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート