首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >python如何获取BytesIO分配的内存长度?

python如何获取BytesIO分配的内存长度?
EN

Stack Overflow用户
提问于 2014-11-09 18:02:28
回答 3查看 38.9K关注 0票数 35

这是我用来测试内存分配的代码

代码语言:javascript
复制
import pycurl
import io


url = "http://www.stackoverflow.com"
buf = io.BytesIO()


print(len(buf.getvalue()))   #here i am getting 0 as length


c = pycurl.Curl()
c.setopt(c.URL, url)
c.setopt(c.CONNECTTIMEOUT, 10)
c.setopt(c.TIMEOUT, 10)
c.setopt(c.ENCODING, 'gzip')
c.setopt(c.FOLLOWLOCATION, True)
c.setopt(c.IPRESOLVE, c.IPRESOLVE_V4)
c.setopt(c.USERAGENT, 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:8.0) Gecko/20100101 Firefox/8.0')
c.setopt(c.WRITEFUNCTION, buf.write)
c.perform()
c.close()

print(len(buf.getvalue()))    #here length of the dowloaded file


print(buf.getvalue())
buf.close()

如何通过BytesIO获取分配的缓冲区/内存长度?我在这里做错了什么?python没有分配固定的缓冲区长度吗?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2014-11-09 18:56:17

我不确定您所说的分配的缓冲区/内存长度是什么意思,但是如果您想要存储在BytesIO对象中的用户数据的长度,您可以这样做

代码语言:javascript
复制
>>> bio = io.BytesIO()
>>> bio.getbuffer().nbytes
0
>>> bio.write(b'here is some data')
17
>>> bio.getbuffer().nbytes
17

但这似乎等同于您当前使用的len(buf.getvalue())

可以使用sys.getsizeof()找到BytesIO对象的实际大小

代码语言:javascript
复制
>>> bio = io.BytesIO()
>>> sys.getsizeof(bio)
104

或者你可以让人讨厌,直接调用__sizeof__() (类似于sys.getsizeof(),但是没有垃圾收集器的开销):

代码语言:javascript
复制
>>> bio = io.BytesIO()
>>> bio.__sizeof__()
72

BytesIO的内存是根据需要分配的,并且确实会发生一些缓冲:

代码语言:javascript
复制
>>> bio = io.BytesIO()
>>> for i in range(20):
...     _=bio.write(b'a')
...     print(bio.getbuffer().nbytes, sys.getsizeof(bio), bio.__sizeof__())
...
1 106 74
2 106 74
3 108 76
4 108 76
5 110 78
6 110 78
7 112 80
8 112 80
9 120 88
10 120 88
11 120 88
12 120 88
13 120 88
14 120 88
15 120 88
16 120 88
17 129 97
18 129 97
19 129 97
20 129 97
票数 70
EN

Stack Overflow用户

发布于 2019-01-04 06:48:44

io.BytesIO()返回一个具有tell()函数的标准文件对象。它报告当前的描述符位置,并且不复制整个缓冲区来计算总大小作为bio.getbuffer().nbyteslen(bio.getvalue())。这是一种非常快速和简单的方法,可以在buffer对象中获得已用内存的确切大小。

但是,如果预设缓冲区,tell()将指向缓冲区的开头并返回0,但缓冲区大小不为零。在这种情况下,您可以将指针移动到buffer chank的末尾,这将报告总的缓冲区大小,而无需将整个缓冲区复制到内存的另一个seek(0,2)中。

我最近更新了一个示例代码和一个更详细的答案here

票数 8
EN

Stack Overflow用户

发布于 2020-04-28 07:55:21

还可以通过在tracemalloc.get_traced_memory()中包装内存事件,使用tracemalloc间接获取有关对象大小的信息

请注意,程序的活动线程(如果有的话)和副作用将影响输出,但如果采样较多,它也可能更能代表实际内存成本,如下所示。

代码语言:javascript
复制
>>> import tracemalloc
>>> from io import BytesIO
>>> tracemalloc.start()
>>>
>>> memory_traces = []
>>>
>>> with BytesIO() as bytes_fh:
...     # returns (current memory usage, peak memory usage)
        # ..but only since calling .start()
...     memory_traces.append(tracemalloc.get_traced_memory())
...     bytes_fh.write(b'a' * (1024**2))  # create 1MB of 'a'
...     memory_traces.append(tracemalloc.get_traced_memory())
...
1048576
>>> print("used_memory = {}b".format(memory_traces[1][0] - memory_traces[0][0]))
used_memory = 1048870b
>>> 1048870 - 1024**2  # show small overhead
294  
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26827055

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档