python生成器性能测试

本文参考自python生成器

在创建大容量列表时,列表中元素的数量很多,会导致列表占用的内存空间很大。这种情况下,如果能能记录列表中的当前的元素值以及计算下一个元素的算法(类似于迭代器),那么相当于内存中只需要存储一个元素以及一段算法,内存占用率将显著降低。生成器就是python提供的这样一种对象,他也是一种迭代器。本文通过一个自然数列表求和的方法,比较列表和生成器对内存的占用率。

0. 内存统计函数

echo >  memory_statistics.txt
while true
do
now_time=$(date "+%Y-%m-%d %H:%M:%S")
memory_usage=`free -h |grep Mem | awk '{print $3}'`
echo -n  $now_time >> memory_statistics.txt
echo  "   $memory_usage" >>  memory_statistics.txt
sleep 0.5
done

该函数将会每个0.5秒记录系统内存的使用率

 

1. 先看一段自然数求和的函数

import datetime

def firstn(n):
    num, nums = 0, []
    while num < n:
        nums.append(num)
        num += 1

    return nums

if __name__ == "__main__":
    print datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
    a = firstn(20000000)
    print datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
    suma = sum(a)
    print datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
    print suma

很简单的函数,先生成一个0到n的列表,然后求和,这段时间内的内存使用率统计如下:

可以看到在2018-08-08 22:41:31到2018-08-08 22:41:34这段时间内,内存急速增加,占用了600M左右内存。同时可见,构造列表花了3秒,sum函数求和用的时间反倒很少。

 

2. 接下来我们来实现一种迭代器

import datetime

class Firstn(object):
    def __init__(self, n):
        self.n = n
        self.num = 0
        self.nums = []

    def __iter__(self):
        return self

    def __next__(self):
        return self.next()

    def next(self):
        if self.num < self.n:
            cur, self.num = self.num, self.num + 1
            return cur
        else:
            raise StopIteration()

print datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
firstn = Firstn(20000000)
print datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
print sum(firstn)
print datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')

这段函数首先构造了一个迭代器,可以这个迭代器保存当前的元素(self.num)和求计算下一个元素的算法(当前元素增加1),我们来看看这个迭代器的性能

我们可以看到内存使用率增加3M,迭代器产生速度远快于列表,但是在求和阶段,花费了9秒的时间,也远多于列表求和。从这里也可以看出,空间和时间不可兼得。

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值