与CPython相比,PyPy占用大量内存
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了与CPython相比,PyPy占用大量内存,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3694字,纯文字阅读大概需要6分钟。
内容图文
我使用python来解决SPOJ的大输入测试problem并遇到了一个非常奇怪的事情.我提交了同样的内容
使用PyPy和Python 2的代码.结果如下所示:
正如预期的那样,与CPython相比,使用PyPy的代码运行得更快.但与此同时,内存使用量增加了7倍!我在网上进行了搜索,但我找不到任何证据表明PyPy的内存使用量远远超过CPython.可以somone请解释内存使用量的巨大差异?
我也认为可能是因为我的代码.因此,我在下面发布了我的代码:
import io, sys, atexit, os
sys.stdout = io.BytesIO()
atexit.register(lambda: sys.__stdout__.write(sys.stdout.getvalue()))
sys.stdin = io.BytesIO(sys.stdin.read())
raw_input = lambda: sys.stdin.readline().rstrip()
line = list(map(int,raw_input().split()))
num, k = line
ans = 0
for i in xrange(0,num):
if int(raw_input())%k == 0:
ans += 1;
print(ans)
有人可以告诉我吗?
解决方法:
首先,我无法重现结果.不知道SPOJ使用了哪些版本/设置.对于以下实验,使用PyPy 5.8.0和CPython 2.7.12.
作为测试用例,使用了大小约为110MB的最大可能输入文件:
#create_data.py
print 10**6, 33
for i in xrange(10**6):
print 10**9
>> python create_data.py > input.in
现在运行/usr/bin/time -v XXX solution.py< input.py产量:
Interpreter MaximalResidentSize
PyPy: 278 Mb
CPython: 222 Mb
PyPy需要更多的内存. CPython和PyPy使用不同的垃圾收集器策略,我认为PyPy的权衡更快,但要使用更多的内存.来自PyPy的人有一个关于垃圾收集器的great article以及它与CPython的比较.
其次,我不相信SPJO网站上的数字. system.stdin.read()将整个文件读入内存. python文档甚至says:
To read a file’s contents, call f.read(size), which reads some quantity of data and returns it as a string. size is an optional numeric argument. When size is omitted or negative, the entire contents of the file will be read and returned; it’s your problem if the file is twice as large as your machine’s memory.
根据假设,最坏的情况是包含在他们的测试用例中,内存使用量至少应该是文件的大小(110 MB),因为你使用std.stdin.read()甚至是两倍大小,因为你是应对数据.
实际上,我不确定,整个麻烦是值得的 – 使用raw_input()可能足够快 – 我只相信python做正确的事情. CPython通常缓冲stdout和stdin(如果将它们重定向到文件,则完全缓冲,或者为控制台进行行缓冲),并且必须使用命令行选项-u到switch it off.
但是如果你真的想确定,你可以使用sys.stdin的文件对象迭代器,因为CPython手册页状态:
-u Force stdin, stdout and stderr to be totally unbuffered. On
systems where it matters, also put stdin, stdout and stderr in
binary mode. Note that there is internal buffering in xread‐
lines(), readlines() and file-object iterators (“for line in
sys.stdin”) which is not influenced by this option. To work
around this, you will want to use “sys.stdin.readline()” inside
a “while 1:” loop.
这意味着您的程序可能如下所示:
import sys
num, k = map(int,raw_input().split())
ans = 0
for line in sys.stdin:
if int(line)%k == 0:
ans += 1
print(ans)
这具有很大的优势,即该变体仅使用大约7MB的内存.
另一个教训是,如果你害怕,你不应该使用sys.stdin.readline(),有人在无缓冲模式下运行你的程序.
一些进一步的实验(我的cpu时钟下降)
CPython CPython -u PyPy PyPy -u
original 28sec/221MB 25sec/221MB 3sec/278MB 3sec/278MB
raw_input() 29sec/7MB 110sec/7MB 7sec/75MB 100sec/63MB
readline() 38sec/7MB 130sec/7MB 5sec/75MB 100sec/63MB
readlines() 20sec/560MB 20sec/560MB 4sec/1.4GB 4sec/1.4G
file-iterator 17sec/7MB 17sec/7MB 4sec/68MB 100sec/62MB
有一些要点:
> raw_input()和sys.stdin.read_line()具有相同的性能
> raw_input()是缓冲的,但是这个缓冲区似乎与file-object迭代器的缓冲区略有不同,它至少对于这个文件来说优于raw_input().
> sys.stdin.readlines()的内存开销似乎非常高,至少只要行很短.
> file-object iterator在CPython和PyPy中有不同的行为,如果使用选项-u:对于PyPy -u也关闭文件对象迭代器的缓冲(可能是一个bug?).
内容总结
以上是互联网集市为您收集整理的与CPython相比,PyPy占用大量内存全部内容,希望文章能够帮你解决与CPython相比,PyPy占用大量内存所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。