Python 内存占用也太大了。

2018-09-25 10:12:15 +08:00
 skinny

我现有 5 个 collections.Counter 的 pickle 文件,单个文件在 84MB-240MB 之间,总共 664MB,总记录在 3 千多万,实际数据大小也就 400MB 左右。之所以分为 5 个文件是因为之前有几个 GB 的数据,我电脑内存小( 6GB ),又是机械硬盘,根本没办法一下子读取和处理,我分割成小块处理,最后变成了这 5 个文件,然后我想合并这些文件进行最后处理。

最终合并前,我预估过用 C 实现类似的字典( D[char[10],uint])合并,内存用的不会很多,即便是最粗糙的字典实现也只需要 680M 左右内存,我看 pickle 文件加起来才 664MB,就算翻 4 翻的内存占用机器也撑得住,可是一运行内存就被耗光,然后机器死机了,只能强制关机,根据死机前的 Python 占用情况,最终可能需要内存要 6GB-8GB 才能加载处理总共 664M 的这 5 个 pickle 文件。(只有 load 和 plus 操作)

可能有人会问我为什么不用 Redis 或者数据库查询,因为我没安装,我也就这一次需要以这种方式处理这种文件。前面用 Python 处理单个小文件时还好,虽然速度不敢恭维,不过还能接受,胜在写起来简单方便。

目前对 Python 感受就是慢、吃内存,但是写起来简单(当然也有非常复杂的,比如 asynio ),真的是胶水一样的语言。

22650 次点击
所在节点    Python
98 条回复
zhengxiaowai
2018-09-25 10:19:09 +08:00
没懂、、、
LokiSharp
2018-09-25 10:22:05 +08:00
这种情况用 C 写扩展啊。。。。
zk8802
2018-09-25 10:22:59 +08:00
用 PyPy 试试。
shyling
2018-09-25 10:23:36 +08:00
别用 pickle
simonliu2018
2018-09-25 10:32:52 +08:00
从磁盘文件 load 到内存里体积都会变大,换做其他序列化方式也是这样,这不是 python 特有的。

换个角度思考这个问题,各种资源总是有限的,工程师要做的就是在各种资源受限的情况下把事情搞定。
Rehtt
2018-09-25 10:34:58 +08:00
用 golang
songdg
2018-09-25 10:36:32 +08:00
试一下 pytable。
ltoddy
2018-09-25 10:38:37 +08:00
去看看 linecache. 还有遇到大的东西,尽量用增量的方式去解决.
xiaoheijw
2018-09-25 10:42:05 +08:00
pickle 是对象序列化,当然吃内存了,大文件建议用 hdf5。
kios
2018-09-25 10:43:16 +08:00
@xiaoheijw 赞同!
skinny
2018-09-25 10:47:52 +08:00
@shyling
@xiaoheijw

我写的一次性处理脚本,以前处理的都是以行或块为单位的,这次第一次处理全部都需要载入处理的,看文件不大,就用了标准库,没想到内存占用大得离谱。
skinny
2018-09-25 10:50:43 +08:00
@simonliu2018
@LokiSharp

知道会内存使用会变得多,没想到的是会这么多,差不多是实际数据的十几倍,预估错了所以没有用 C。
UN2758
2018-09-25 11:05:16 +08:00
文本反序列化一般 10 倍内存起步吧,python 而言
lihongjie0209
2018-09-25 11:07:07 +08:00
sqlite 不需要安装吧, 可以试一下
est
2018-09-25 11:11:24 +08:00
明明是自己不会用 pickle 非得用 pickle。怪到一个语言上?
lihongjie0209
2018-09-25 11:17:20 +08:00
要不这样, 你发一个测试文件出来, 大家一起用 python 标准库写一遍, 看看能不能在你的硬件条件下实现你的需求, 光说不做测试没意义
skinny
2018-09-25 11:18:12 +08:00
@lihongjie0209 用了,太慢了。
dychenyi
2018-09-25 11:24:10 +08:00
mmap 了解一下,磁盘映射读取
skinny
2018-09-25 11:30:39 +08:00
@est 你这人真是莫名其妙,我从来就没说 pickle 什么事,我只说了 Python 对象内存占用多,对象 load 以后是 Counter 对象,你是不是还要说我不会用 Counter ? Counter 是 dict 子类,是不是还要说我不会用 dict ? dict 里存了太多文本是不是还得说我不会用 str ?
sunnyadamm
2018-09-25 11:38:26 +08:00
with open() as f 了解一下

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/492253

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX