为了账号安全,请及时绑定邮箱和手机立即绑定

PHP可变长参数(...)和生成器问题

PHP可变长参数(...)和生成器问题

PHP
神不在的星期二 2019-03-15 11:34:11
问题来源于 https://segmentfault.com/q/10... 这里。看了@elarity 的回答,他使用了200000的元素插入到redis集合。于是乎我使用了1百万个元素数组来插入,在我这里是内存溢出的,所以我使用了生成器的方式 function xrange() { for ($i=0; $i<1000000; $i++) { yield $i; } } $r = xrange(); $redis = new Redis(); $redis->connect('127.0.0.1', 6379); $key = 'jimu'; $redis->del($key); $begin = microtime(true); $redis->sadd($key, ...$r); $end = microtime(true); echo ($end - $begin) . "\n"; 输出结果: [vagrant@localhost ~]$ php redis.php 1.2786898612976 [vagrant@localhost ~]$ 然后redis-cli中确实有了一百万个元素。那么当我把代码中的一百万修改为一千万的时候又报内存溢出 [vagrant@localhost ~]$ php redis.php PHP Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 32 bytes) in /home/vagrant/redis.php on line 6 Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 32 bytes) in /home/vagrant/redis.php on line 6 根据我理解的生成器知识不应该出现内存溢出的情况。因为自始至终生成器xrange只占用一个变量($i)内存?所以我猜测是不是$redis->sadd($key, ...$r);这一步的时候...$r依然会解析成大数组。 现在不知道如何证实。 补充:我在sadd之前使用var_dump(...$r);exit;发现输出的都是 int(999775) int(999776) int(999777) int(999778) int(999779) int(999780) int(999781) 这样可以证明生成器确实是一个一个产出值的。那么为什么将...$r传入到sadd()的时候还报内存不足呢?不明白这个...的原理,还请大佬们指点。
查看完整描述

2 回答

?
噜噜哒

TA贡献1784条经验 获得超7个赞

您说的这个问题 , 我也知道 . 但没有深究 . 借着这次机会 , 工作完了后一会儿我也深究一下 .
最简单 , 可以先用 memory_get_usage 来简单测试一下 .

感谢补刀

查看完整回答
反对 回复 2019-03-18
  • 2 回答
  • 0 关注
  • 646 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信