0

0

奇怪的PHP引用效率问题分析_php技巧

php中文网

php中文网

发布时间:2016-05-17 09:11:56

|

1287人浏览过

|

来源于php中文网

原创

函数如下:

羚珑
羚珑

京东推出的一站式AI图像处理平台

下载
复制代码 代码如下:

function update_timelist(&$arr,$timestamp,$threshold){
$timequeue = &$arr['timequeue'];
while(!empty($timequeue[0])&&($timestamp-$timequeue[0])>$threshold){
array_shift($timequeue);
}
array_push($timequeue, $timestamp);
if($arr['count']$arr['count'] = count($timequeue);
}
}

大家看出来这个函数有什么问题了没有?其实,有很大一个问题,就是函数中的:

$timequeue = &$arr['timequeue'];

这一行导致程序读入22M数据并生成时间节点链表用了接近40秒,而删掉该行改成直接使用$arr['timequeue']时间就缩短了30秒,只需要10秒左右就处理完了22M。
复制代码 代码如下:

function update_timelist(&$arr,$timestamp,$threshold){
while(!empty($arr['timequeue'][0])&&($timestamp-$arr['timequeue'][0])>$threshold){
array_shift($arr['timequeue']);
}
array_push($arr['timequeue'], $timestamp);
if($arr['count']$arr['count'] = count($arr['timequeue']);
}

大家看出来是什么问题了吗?问题就count函数上,没有想到吧。PHP将变量指向的真正的内容空间标记为了引用类型和非引用类型,像下面的代码:
复制代码 代码如下:

$a = 'jb51.net';
$b = $a;
$c = $b;

实际占用内存空间只有一份,因为PHP的zend引擎使用copy on writing的机制,只在$b,$c修改的时候才会复制一份'jb51.net'过来,此时'jb51.net'的内容空间类型为非引用类型,如果改为下面的代码:
复制代码 代码如下:

$a = 'jb51.net';
$b = $a;
$c = &$a;

这个会有什么变化?仍然是一份内存空间存放'jb51.net'吗?不是,因为$c为$a的引用,$a的指向的存储空间需要标记为引用类型,那么必须为$b单独复制一份'jb51.net'才行了,因为$b指向的是非引用类型。
我们可以这样理解,$c现在是$a的引用了,如果$b仍然执行$a的空间那么修改$c将导致$b也修改,所以此时一旦出现引用即使没有写操作也必须复制一份了。也可以这样理解,php对变量指向的内存空间只有非引用和引用两种类型,两种类型不能混合,不能转移。如果什么地方需要改变内存空间的状态则需要copy一份了。
下面就说明为什么多了$timequeue = &$arr['timequeue']会导致count变慢,还记得c函数的调用过程吗?实际我们传入的参数需要copy一份拷贝传入,php也一样,但是由于copy on writing机制使得count在传入非引用类型时是不会真正copy的,但是$timequeue = &$arr['timequeue']将$timequeue的内存空间指定为了引用类型,而count需要非引用类型,这样就导致count需要copy一份$arr['timequeue']了。直接传入$arr['timequeue']为什么没有问题?count当然是用了copy on writing的机制,array_shift和array_push呢?他们是传入的引用啊,不用担心这不是修改了$arr['timequeue']的类型而是真正的传入了$arr['timequeue']的一个别名。

对于PHP我也是刚刚开始学习,上面的分析不一定正确,也不一定全面。大家可以在我的主页发邮件留言与我交流。

相关专题

更多
Word 字间距调整方法汇总
Word 字间距调整方法汇总

本专题整合了Word字间距调整方法,阅读下面的文章了解更详细操作。

2

2025.12.24

任务管理器教程
任务管理器教程

本专题整合了任务管理器相关教程,阅读下面的文章了解更多详细操作。

2

2025.12.24

AppleID格式
AppleID格式

本专题整合了AppleID相关内容,阅读专题下面的文章了解更多详细教程。

0

2025.12.24

csgo视频观看入口合集
csgo视频观看入口合集

本专题整合了csgo观看入口合集,阅读下面的文章了知道更多入口地址。

29

2025.12.24

yandex外贸入口合集
yandex外贸入口合集

本专题汇总了yandex外贸入口地址,阅读下面的文章了解更多内容。

58

2025.12.24

添加脚注通用方法
添加脚注通用方法

本专题整合了添加脚注方法合集,阅读专题下面的文章了解更多内容。

1

2025.12.24

重启电脑教程汇总
重启电脑教程汇总

本专题整合了重启电脑操作教程,阅读下面的文章了解更多详细教程。

3

2025.12.24

纸张尺寸汇总
纸张尺寸汇总

本专题整合了纸张尺寸相关内容,阅读专题下面的文章了解更多内容。

5

2025.12.24

Java Spring Boot 微服务实战
Java Spring Boot 微服务实战

本专题深入讲解 Java Spring Boot 在微服务架构中的应用,内容涵盖服务注册与发现、REST API开发、配置中心、负载均衡、熔断与限流、日志与监控。通过实际项目案例(如电商订单系统),帮助开发者掌握 从单体应用迁移到高可用微服务系统的完整流程与实战能力。

1

2025.12.24

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
CSS3 教程
CSS3 教程

共18课时 | 4万人学习

Django 教程
Django 教程

共28课时 | 2.4万人学习

Bootstrap 5教程
Bootstrap 5教程

共46课时 | 2.6万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号