您当前的位置: 首页 > 网站编程 > PHP教程 > PHP前端开发中的性能那点事

PHP前端开发中的性能那点事

作者:不详 来源:网络 发布时间: 2014-08-12 18:00 点击:
在我们平时的php开发中,一个大的项目经过长时间的积累以后你会发现性能越来越慢,而性能到底消耗在了什么地方,常常是一个令人头疼的问题,function a()调用了多少次,function b()又消耗了多少时间,我们到底怎么查找是哪个蛀虫拉慢了我们的程序运行速度呢?在这里给

PHP前端开发中的性能那点事

  在我们平时的php开发中,一个大的项目经过长时间的积累以后你会发现性能越来越慢,而性能到底消耗在了什么地方,常常是一个令人头疼的问题,function a()调用了多少次,function b()又消耗了多少时间,我们到底怎么查找是哪个蛀虫拉慢了我们的程序运行速度呢?在这里给大家介绍一款工具xdebug,相信很多人已经听说过了,希望借助这个工具我们可以起到简单分析php程序性能瓶颈的问题。

  A)假设1,假设用户目录在/home/ad

  B)假设2,假设php目录在/home/ad/php

  1、xdebug简介与安装

  Xdebug是一个开放源代码的PHP程序调试器(即一个Debug工具),可以用来跟踪,调试和分析PHP程序的运行状况。

  1)下载xdebug

  xdebug的官方下载地址为:http://xdebug.org/download.php

  最新版本为:Xdebug 2.1.0

  2)xdebug的安装

  

  

  

  

  

  

  

  


  1

  2

  3

  4

  5

  6

  7

  8

  


  cd /home/ad

  wget http://xdebug.org/files/xdebug-2.1.0.tgz

  tar -zxvf xdebug-2.1.0.tgz

  cd xdebug-2.1.0

  /home/ad/php/bin/phpize

  ./configure --enable-xdebug --with-php-config=/home/ad/php/bin/php-config

  make

  make install

  


  安装完以后会提示你扩展安装到了哪个目录,类似 /home/ad/php/lib/php/extensions/no-debug-non-zts-20060613/

  假设你的php.ini放在 /home/ad/php/lib/php.ini

  加上

  

  

  

  

  

  

  

  


  1

  2

  3

  4

  5

  6

  7

  8

  9

  


  [xdebug]

  zend_extension = "/home/ad/php/lib/php/extensions/no-debug-non-zts-20060613/xdebug.so"

  xdebug.auto_trace = on

  xdebug.auto_profile = on

  xdebug.collect_params = on

  xdebug.collect_return = on

  xdebug.profiler_enable = on

  xdebug.trace_output_dir = "/home/ad/xdebug_log"

  xdebug.profiler_output_dir = "/home/ad/xdebug_log"

  


  重启apache

  去/home/ad/xdebug_log下看看是不是日志已经出来了

  2、xdebug参数简介

  zend_extension 加载xdebug扩展

  xdebug.auto_trace 自动打开打开函数调用监测

  xdebug.auto_profile 自动打开性能监测

  xdebug.trace_output_dir 设定函数调用监测信息的输出文件的路径。

  xdebug.profiler_output_dir 设定效能监测信息输出文件的路径。

  xdebug.collect_params 打开收集“函数参数”的功能。将函数调用的参数值列入函数过程调用的监测信息中。

  xdebug.collect_return 打开收集“函数返回值”的功能。将函数的返回值列入函数过程调用的监测信息中。

  3、示例程序与日志收集

  

  

  

  

  

  

  

  


  1

  2

  3

  4

  5

  6

  7

  8

  9

  10

  11

  12

  13

  14

  15

  


  <?php

  function a()

  {

      echo "aaa";  

  }

  function b()

  {

      a();

      sleep(1);

      a();

      sleep(1);

      a();  

  }

  b();

  ?>

  


  4、日志分析工具wincachegrind

  http://sourceforge.net/projects/wincachegrind/

  不用安装直接双击就可以打开了

  我们用它打开刚才收集的日志cachegrind.out.***



  前端开发中的性能那点事(二)巧用curl 并发减少后端访问时间

  前言:

  在我们平时的程序中难免出现同时访问几个接口的情况,平时我们用curl进行访问的时候,一般都是单个、顺序访问,假如有3个接口,每个接口耗时500毫秒那么我们三个接口就要花费1500毫秒了,这个问题太头疼了严重影响了页面访问速度,有没有可能并发访问来提高速度呢?今天就简单的说一下,利用curl并发来提高页面访问速度,

  希望大家多指导。

  1、老的curl访问方式以及耗时统计

  

  

  

  

  

  

  

  


  1

  2

  3

  4

  5

  6

  7

  8

  9

  10

  11

  12

  13

  14

  15

  16

  17

  18

  19

  20

  21

  22

  23

  24

  25

  26

  27

  28

  29

  30

  31

  32

  33

  34

  


  <?php

  function curl_fetch($url, $timeout=3){

      $ch = curl_init();

      curl_setopt($ch, CURLOPT_URL, $url);

      curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);

      curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

      $data = curl_exec($ch);

      $errno = curl_errno($ch);

      if ($errno>0) {

          $data = false;

      }

      curl_close($ch);

      return $data;

  }

  function microtime_float()

  {

     list($usec, $sec) = explode(" ", microtime());

     return ((float)$usec + (float)$sec);

  }

  $url_arr=array(

       "taobao"=>"http://www.taobao.com",

       "sohu"=>"http://www.sohu.com",

       "sina"=>"http://www.sina.com.cn",

       );

  $time_start = microtime_float();

  $data=array();

  foreach ($url_arr as $key=>$val)

  {

       $data[$key]=curl_fetch($val);

  }

  $time_end = microtime_float();

  $time = $time_end - $time_start;

  echo "耗时:{$time}";

  ?>

  


  耗时:0.614秒

  2、curl并发访问方式以及耗时统计

  

  

  

  

  

  

  

  


  1

  2

  3

  4

  5

  6

  7

  8

  9

  10

  11

  12

  13

  14

  15

  16

  17

  18

  19

  20

  21

  22

  23

  24

  25

  26

  27

  28

  29

  30

  31

  32

  33

  34

  35

  36

  37

  38

  39

  40

  41

  42

  43

  44

  45

  46

  47

  48

  49

  50

  51

  52

  53

  54

  55

  56

  57

  58

  59

  60

  61

  62

  63

  64

  65

  66

  67

  68

  69

  70

  


  <?php

  function curl_multi_fetch($urlarr=array()){

      $result=$res=$ch=array();

      $nch = 0;

      $mh = curl_multi_init();

      foreach ($urlarr as $nk => $url) {

          $timeout=2;

          $ch[$nch] = curl_init();

          curl_setopt_array($ch[$nch], array(

          CURLOPT_URL => $url,

          CURLOPT_HEADER => false,

          CURLOPT_RETURNTRANSFER => true,

          CURLOPT_TIMEOUT => $timeout,

          ));

          curl_multi_add_handle($mh, $ch[$nch]);

          ++$nch;

      }

      /* wait for performing request */

      do {

          $mrc = curl_multi_exec($mh, $running);

      } while (CURLM_CALL_MULTI_PERFORM == $mrc);

   

      while ($running && $mrc == CURLM_OK) {

          // wait for network

          if (curl_multi_select($mh, 0.5) > -1) {

              // pull in new data;

              do {

                  $mrc = curl_multi_exec($mh, $running);

              } while (CURLM_CALL_MULTI_PERFORM == $mrc);

          }

      }

   

      if ($mrc != CURLM_OK) {

          error_log("CURL Data Error");

      }

   

      /* get data */

      $nch = 0;

      foreach ($urlarr as $moudle=>$node) {

          if (($err = curl_error($ch[$nch])) == '') {

              $res[$nch]=curl_multi_getcontent($ch[$nch]);

              $result[$moudle]=$res[$nch];

          }

          else

          {

              error_log("curl error");

          }

          curl_multi_remove_handle($mh,$ch[$nch]);

          curl_close($ch[$nch]);

          ++$nch;

      }

      curl_multi_close($mh);

      return  $result;

  }

  $url_arr=array(

       "taobao"=>"http://www.taobao.com",

       "sohu"=>"http://www.sohu.com",

       "sina"=>"http://www.sina.com.cn",

       );

  function microtime_float()

  {

     list($usec, $sec) = explode(" ", microtime());

     return ((float)$usec + (float)$sec);

  }

  $time_start = microtime_float();

  $data=curl_multi_fetch($url_arr);

  $time_end = microtime_float();

  $time = $time_end - $time_start;

  echo "耗时:{$time}";

  ?>

  


  耗时:0.316秒

  帅气吧整个页面访问后端接口的时间节省了一半

  3、curl相关参数

  来自:http://cn2.php.net/manual/en/ref.curl.php

  curl_close — Close a cURL session

  curl_copy_handle — Copy a cURL handle along with all of its preferences

  curl_errno — Return the last error number

  curl_error — Return a string containing the last error for the current session

  curl_exec — Perform a cURL session

  curl_getinfo — Get information regarding a specific transfer

  curl_init — Initialize a cURL session

  curl_multi_add_handle — Add a normal cURL handle to a cURL multi handle

  curl_multi_close — Close a set of cURL handles

  curl_multi_exec — Run the sub-connections of the current cURL handle

  curl_multi_getcontent — Return the content of a cURL handle if CURLOPT_RETURNTRANSFER is set

  curl_multi_info_read — Get information about the current transfers

  curl_multi_init — Returns a new cURL multi handle

  curl_multi_remove_handle — Remove a multi handle from a set of cURL handles

  curl_multi_select — Wait for activity on any curl_multi connection

  curl_setopt_array — Set multiple options for a cURL transfer

  curl_setopt — Set an option for a cURL transfer

  curl_version — Gets cURL version information

  前端开发中的性能那点事(三)php的opcode缓存

  前言:由php的运行机制决定,其实php在运行阶段我们也是可以进行缓存的从而提高程序运行效率,这就是我们常说的opcode缓存。

  1、简述php的运行机制

  (因为本文是写opcode缓存的所以这里只是简要概述,后边会专门写一篇揭秘php运行机制的。)

  a).php文件通过浏览器过来

  b)请求交给SAPI,随后SAPI层将控制权转给PHP

  c)zend_language_scanner对代码进行扫描,对php代码进行词法分析转换成一系列的tokens array

  d)zend_language_parser将c步骤产生的一系列tokens处理掉空格等无用的代码以后转换成一系列表达式

  e)经过compiler阶段生成opcode返回zend_op_array指针

  f)zend_vm_execute根据传入的zend_op_array指针,执行opcode并将结果返回输出

  


  2、opcode简介

  Opcode是operation code(操作码)的简称,其实就是第一小节c)、d)、e)步骤产生的一种中间码,

  opcode是一个四元组,(opcode, op1, op2, result),它们分别代表操作码,第一操作数,第二操作数,结果。

  如:

  

  

  

  

  

  

  

  


  1

  2

  3

  


  <?php

  echo "taobao search blog";

  ?>

  


  对应的tokens

  

  

  

  

  

  

  

  


  1

  2

  3

  4

  5

  6

  7

  8

  9

  10

  11

  12

  13

  14

  15

  16

  17

  18

  19

  20

  21

  22

  23

  24

  25

  26

  27

  28

  29

  30

  31

  32

  33

  34

  35

  36

  37

  38

  39

  40

  41

  42

  43

  44

  45

  46

  


  Array

  (

      [0] => Array

          (

              [0] => 367

              [1] => <?php

              [2] => 1

          )

   

      [1] => Array

          (

              [0] => 316

              [1] => echo

              [2] => 1

          )

   

      [2] => Array

          (

              [0] => 370

              [1] =>

              [2] => 1

          )

   

      [3] => Array

          (

              [0] => 315

              [1] => "taobao search blog"

              [2] => 1

          )

   

      [4] => ;

      [5] => Array

          (

              [0] => 370

              [1] =>

              [2] => 1

          )

   

      [6] => Array

          (

              [0] => 369

              [1] => ?>

              [2] => 1

          )

   

  )

  


  对应的opcode就是

  

  

  

  

  

  

  

  


  1

  2

  3

  4

  5

  


  line    # * op                          fetch         ext  return  operands

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

     2    0 >   ECHO                                                     'taobao+search+blog'

     4    1   > RETURN                                                  1

           2*  > ZEND_HANDLE_EXCEPTION

  


  3、使用apc对opcode缓存

  a)假设php路径为/home/ad/php

  对opcode进行缓存的软件很多(apc、eAcclerator、Xcache、Zend Platform),这里主要介绍apc

  APC提供两种缓存功能,即缓存Opcode(目标文件),我们称之为apc_compiler_cache。同时它还提供一些接口用于PHP开发人员将用户数据驻留在内存中,我们称之为apc_user_cache。我们这里主要讨论apc_compiler_cache的配置。

  下载地址:http://pecl.php.net/package/APC

  最新版本为APC-3.1.6.tgz

  

  

  

  

  

  

  

  


  1

  2

  3

  4

  5

  6

  7

  


  wget http://pecl.php.net/get/APC-3.1.6.tgz

  tar -zxvf APC-3.1.6.tgz

  cd APC-3.1.6

  /home/ad/php/bin/phpize

  ./configure --enable-apc --enable-apc-mmap --with-php-config=/home/ad/php/bin/php-config

  make

  make install

  


  编辑php.ini

  添加apc的配置

  

  

  

  

  

  

  

  


  1

  2

  3

  4

  5

  6

  7

  8

  9

  10

  11

  12

  13

  


  [apc]

  extension=apc.so

  apc.enabled=1

  apc.shm_segments = 1

  apc.shm_size = 128

  apc.ttl = 0

  apc.user_ttl = 7200

  apc.num_files_hint = 1000

  apc.write_lock=1

  apc.stat = 0

  apc.max_file_size=1M

  apc.filters = a.php,b.php

  apc.cache_by_default=1

  


  重新apache就ok啦

  4、常用参数的解析

  apc.enabled 开启apc 设置为0关闭,1为开启

  apc.shm_segments 共享内存块数

  apc.shm_size 共享内存大小,但是是M

  那么显然共享内存的总数就是apc.shm_segments*apc.shm_size

  apc.num_files_hint 允许多少个opcode被缓存

  apc.stat 为1的时候会自动检查opcode对应的php文件是否有更新,有更新的话会自动更新。设置为0的话就不会去检查了这样会提高apc的效率,但是要使php的修改生效的话就必须重启apache了,或者使用函数apc_cache_clear()来清空缓存

  apc.ttl opcode缓存的过期时间,设置为0表示不过期,如果不为0会检查两次请求之间的时间,如果时间大于设置值那么会更新opcode缓存

  apc.write_lock 表示多个进程同时更新一份opcode缓存的时候那么只让最先的一个生效,可以有效避免写冲突

  apc.max_file_size 超过设置值大小的文件不被缓存

  apc.filters 需要特例的文件,多个文件用逗号(,)相隔

  apc.filters 与 apc.cache_by_default结合使用,

  当apc.cache_by_default为1时apc.filters文件不被缓存,当apc.cache_by_default为0时仅apc.filters文件被缓存
分享到:
本文"PHP前端开发中的性能那点事"由远航站长收集整理而来,仅供大家学习与参考使用。更多网站制作教程尽在远航站长站。
顶一下
(0)
0%
踩一下
(0)
0%
[点击 次] [返回上一页] [打印]
发表评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
评价:
表情:
用户名: 密码: 验证码:
关于本站 - 联系我们 - 广告合作 - 网站声明 - 友情连接- 网站地图 - 站点地图 - 返回顶部
Copyright © 2007-2013 www.yhzhan.com(远航站长). All Rights Reserved .
远航站长:为中小站长提供最佳的学习与交流平台,提供网页制作与网站编程等各类网站制作教程.
官方QQ:445490277 网站群:26680406 网站备案号:豫ICP备07500620号-4