Python 中 list 的内存分配及访问的问题

 

该问题源自 StackOverflow 上一名网友提出的问题:

Why is copying a shuffled list much slower?

简单地描述下该问题,复制一个未打乱的list要比复制同样一个但是打乱的list要快很多:

测试代码:

from timeit import timeit
import random
a = range(10**6)
random.shuffle(a)    # Remove this for the second test.
a = list(a)          # Just an attempt to "normalize" the list.
for _ in range(5):
    print timeit(lambda: list(a), number=10)

未打乱时:

0.058402235973
0.0505464636856
0.0509734306934
0.0526022752744
0.0513324916184

打乱后:

0.175597017661
0.173731403198
0.178601711594
0.180330912952
0.180811964451

造成这个现象的主要原因是Python的内存机制,总结相关文章,要点如下:

  1. 所有的Python对象都在堆中分配,甚至是interger对象
  2. list列表中保存着对分配在堆中的对象的指针的数组(array of pointers to the objects).
  3. 复制list只是一个浅操作
  4. 对象被一个新容器引用时,然而python需要增加引用计数,而不是仅仅复制引用。因此,Python必须访问该对象。
  5. 在shuffle前,在堆中分配时,相邻的index的对象在内存中是相邻的,访问时内存命中率很高;而shuffle后,新的list的相邻index的对象在内存中并不是相邻的,命中率非常差。

 

转载于:https://my.oschina.net/u/1791007/blog/836888

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值