首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >程序员进阶-深究函数的传参原理

程序员进阶-深究函数的传参原理

作者头像
sibenx
发布2019-07-19 11:47:57
4190
发布2019-07-19 11:47:57
举报
文章被收录于专栏:城边编程城边编程

在主流的编程语言中,函数是构成程序的最小单元,如果把编程比喻成搬砖那么函数就是砖。搬砖是一门大学问,大多数人搬不好。写函数是更大的学问,许多程序员都写的很糟糕,包括我自己。

今天说说函数编写的错误集锦,怎样写函数会让函数变的特别糟糕,函数的传参在编译器中是如何优化的。

先执行一段代码:

//初始化一个10万的数组
$data = array_fill(0, 100000, '城边编程');
var_dump(memory_get_usage()); 
//复制函数
function cp($arr){
    return $arr;
}
$aa = cp($data);
var_dump(memory_get_usage());

要讲的原理与语言无关,这里var_dump() 是打印函数 memory_get_usage()是获取程序当前的内存使用情况。

运行结果:

数组消耗:int(4593512) 函数消耗:int(4593544)

这段代码执行了cp()函数,并且申明了一个大数组,但是内存没涨(其实涨了32,这也是个有趣的问题,与当前要讲的内容无关,之后单独讲讲)。这是为什么?

在很多年以前,函数中如果要传递数组,编译器会先把数组复制一份,再把复制好的数组传给函数。这样做了一段时间之后发现如果数组太大并且在函数中只读的话复制是没意义的,还特别浪费内存。然后就在编译器中加了一种机制叫『写时复制』,简单理解就是当函数内部要对数组做修改时才会把数组复制一份。

这是函数内部的一种优化方式,在编译器内部很多场合都用到了这种优化方式,下面看代码。

var_dump(memory_get_usage()); 
//初始化一个10万的数组
$data = array_fill(0, 100000, '城边编程');
var_dump(memory_get_usage()); 
//复制函数
function cp($arr){
    $arr[2] = "编程城边";
    return $arr;
}
$aa = cp($data);
var_dump(memory_get_usage());

运行结果:

初始内存:int(395680) 数组消耗:int(4594192) 函数消耗:int(8792672)

只加了一行代码,在函数中对数组做了修改(写操作),于是内存消耗就涨了一倍。

『写复制』在大多数情况下能帮助我们节省内存,如果程序员不知道这个原理,频繁的在函数中对数组进行写操作,会导致代码消耗内存严重,执行效率低下。虽然肉眼看不出程序哪里有问题,而且运行结果也符合预期,但是这不是一段好代码。

这段代码我们应该如何优化呢?

var_dump(memory_get_usage()); 
//初始化一个10万的数组
$data = new ArrayObject(array_fill(0, 100000, '城边编程'));
var_dump(memory_get_usage()); 
//复制函数
function cp($arr){
    $arr[2] = "编程城边";
    return $arr;
}
$aa = cp($data);
var_dump(memory_get_usage());

只需要改一行,改完之后效果如下:

初始内存:int(395688) 数组消耗:int(4594328) 函数消耗:int(4594328)

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-07-12,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 城边编程 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档