首页 > 开发 > PHP > 正文

深入理解PHP内核(一)

2024-05-04 22:34:16
字体:
来源:转载
供稿:网友

PHP作为一门简单而强大的语言,能够提供很多Web适用的语言特性。从实践出发,继弱类型变量原理探究后,本文继续带领大家深入理解php内核。

 最近,和一个网友交流的时候,给我提了一个非常奇怪的问题。那就是,在一个运算中,加了一个引用之后,发现性能慢了一万倍。在我的脑海里面,引用是一个非常容易出错的问题,特别是PHP里面的引用,有非常多的陷阱。因为,以前专门研究过这一块PHP的源代码,所以,我可以比较清晰的解析引用到底是怎么一回事,希望,读了我这篇文章,能彻底理解这个问题。如果,有任何疑问,或者有一些你想了解的问题,可以给我留言。

先来看一段代码:

class RefferTest{ private $data; private $testKey; function __construct() {  $key = "hello";  $this->data[$key] = range(0, 10000);  $this->testKey = $key; } function reffer($key) {  $reffer = &$this->data[$key];  return count($reffer); } function noreffer($key) {  return count($this->data[$key]); } function test() {  $t1 = microtime(true);  for ($i = 0; $i < 5000; $i++)  {   $this->reffer($this->testKey);  }  $t2 = microtime(true) - $t1;  var_dump("reffer: " . round($t2, 4));  $t1 = microtime(true);  for ($i = 0; $i < 5000; $i++)  {   $this->noreffer($this->testKey);  }  $t2 = microtime(true) - $t1;  var_dump("noreffer: " . round($t2, 4)); }}$test = new RefferTest();$test->test();

 如果你完这个代码,能说出,为了reffer 和 noreffer会差一万倍的性能,那下面的也就没有必要往下看了。这篇博客针对的是,PHP的新手。你可以运行一下这个代码试试看,的确差了一万倍。当然,那个网友遇到的问题的代码要比上面的复杂,上面的代码是我为了说明问题,特意简化的。或许你已经从代码里面看出问题了,但是,至于为什么会这样。我想,还是有必要分析一下。这样,以后,在使用PHP的时候,才不会犯相同的错误。

PHP为了减少复制,采用了一种copy on writer的机制。我想,这是一种非常常见的机制,你也一定听说过。比如,gcc 的 stl string 的实现,就是采用这样的机制,字符串赋值,不是真正的复制,而且,在修改的时候才会进行复制。我们先来举个最简单的例子:

 $a = str_repeat("", );  $b = $a;  $a[] = "";

$a 是一个非常大的字符串,如果 $b = $a 的时候,进行复制,那要耗费很多内存 和 cpu,这样非常的不划算,万一,下面的代码并不修改$a 和 $b 那复制根本没有必要。当然,$a 在后面又被修改了,这个时候,必须进行复制了,否则就不符合逻辑了。但是,现在问题来了,怎么知道,$a 在修改的时候,要进行复制呢,必须要有这样一个标记。方法就是采用引用计数。引用计数还被用来进行内存的管理。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表