我现有 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 ),真的是胶水一样的语言。
1
zhengxiaowai 2018-09-25 10:19:09 +08:00
没懂、、、
|
2
LokiSharp 2018-09-25 10:22:05 +08:00
这种情况用 C 写扩展啊。。。。
|
3
zk8802 2018-09-25 10:22:59 +08:00 via iPhone
用 PyPy 试试。
|
4
shyling 2018-09-25 10:23:36 +08:00
别用 pickle
|
5
simonliu2018 2018-09-25 10:32:52 +08:00
从磁盘文件 load 到内存里体积都会变大,换做其他序列化方式也是这样,这不是 python 特有的。
换个角度思考这个问题,各种资源总是有限的,工程师要做的就是在各种资源受限的情况下把事情搞定。 |
6
Rehtt 2018-09-25 10:34:58 +08:00 via Android
用 golang
|
7
songdg 2018-09-25 10:36:32 +08:00
试一下 pytable。
|
8
ltoddy 2018-09-25 10:38:37 +08:00
去看看 linecache. 还有遇到大的东西,尽量用增量的方式去解决.
|
9
xiaoheijw 2018-09-25 10:42:05 +08:00 1
pickle 是对象序列化,当然吃内存了,大文件建议用 hdf5。
|
11
skinny OP |
12
skinny OP |
13
UN2758 2018-09-25 11:05:16 +08:00
文本反序列化一般 10 倍内存起步吧,python 而言
|
14
lihongjie0209 2018-09-25 11:07:07 +08:00
sqlite 不需要安装吧, 可以试一下
|
15
est 2018-09-25 11:11:24 +08:00
明明是自己不会用 pickle 非得用 pickle。怪到一个语言上?
|
16
lihongjie0209 2018-09-25 11:17:20 +08:00
要不这样, 你发一个测试文件出来, 大家一起用 python 标准库写一遍, 看看能不能在你的硬件条件下实现你的需求, 光说不做测试没意义
|
17
skinny OP @lihongjie0209 用了,太慢了。
|
18
dychenyi 2018-09-25 11:24:10 +08:00
mmap 了解一下,磁盘映射读取
|
19
skinny OP @est 你这人真是莫名其妙,我从来就没说 pickle 什么事,我只说了 Python 对象内存占用多,对象 load 以后是 Counter 对象,你是不是还要说我不会用 Counter ? Counter 是 dict 子类,是不是还要说我不会用 dict ? dict 里存了太多文本是不是还得说我不会用 str ?
|
20
sunnyadamm 2018-09-25 11:38:26 +08:00
with open() as f 了解一下
|
21
est 2018-09-25 11:41:00 +08:00 4
|
22
wutiantong 2018-09-25 12:07:23 +08:00
@skinny 人家 est 所 diss 的是“你不会用 pickle 非要强上才导致的问题不应该怪 python ”,你非要理解成他在袒护 pickle,你这边的沟通理解能力堪忧
|
23
billgreen1 2018-09-25 12:10:16 +08:00
@est 我觉得会问问题的人,一般会提供环境,版本号,自己的分析,以及疑问等;楼主最多是不太会问问题,你直接得出不会用,这个结论是难以成立的。
|
24
est 2018-09-25 12:18:51 +08:00
@billgreen1 万一我猜对了呢。
|
25
javaWeber 2018-09-25 12:22:35 +08:00
用 java,上 maven,加 20 个依赖包。。开始写程序。
|
26
GreenHand 2018-09-25 12:38:38 +08:00
试一下其他语言的对象序列化 /反序列化是否占用内存再来吐槽 Python ?
你这种情况不需要用到 pickle 吧?只是 string: integer 的映射而已,直接写到文件不行吗? ``` with open('data.txt', 'w') as f: for i in xrange(30000000): print >>f, '%s:%s' % (str(i), i) ``` 最后一行的分隔符(冒号)替换一下保证 key 里面不包括换行符即可。 |
27
SuperMild 2018-09-25 12:42:28 +08:00
数据库没安装? Python 使用 sqlite 不用安装。
|
28
kernel 2018-09-25 13:27:59 +08:00
楼主要反击也容易,直接写个几行 python 小程序里加 100M 个 int 到一个 dict 里看看最终占多少内存
|
29
lance6716 2018-09-25 13:29:46 +08:00 via Android
Python 对象内存占用太多我还是第一次听说… dict 最近几个版本就是优化了占用
|
30
skinny OP @billgreen1 我从头到尾没有问问题,只是就使用体验的吐槽而已。
@wutiantong 你这更加莫名其妙了,从头到尾没有 pickle 什么事情,我主贴里说了,吐槽的是本来不大的数据,载入转换成 Python 对象以后翻了很多翻,究竟是谁沟通能力、理解能力堪忧? |
32
sagaxu 2018-09-25 13:44:27 +08:00 via Android
py 最小的数据类型,一个对象也是几十字节
|
33
kernel 2018-09-25 13:51:16 +08:00
@lance6716 在处理大量小数据时,比如在 C 里一个 int32 就是 4 字节,python 里要几十字节
当然处理大量小数据一般不是 python 的应用场景,反正我是从来没碰到过 |
34
zhzer 2018-09-25 13:53:13 +08:00 via Android
counter 还储存了频率本来就应该大一点啊
|
35
scriptB0y 2018-09-25 13:56:27 +08:00
还是看一下为什么会占这么多内存: https://pypi.python.org/pypi/memory_profiler
|
36
wutiantong 2018-09-25 14:03:56 +08:00
@skinny 不是,你老说没 pickle 什么事,可是你明明就是在用 pickle 做序列化反序列化啊?
|
37
hahastudio 2018-09-25 14:26:10 +08:00
因为高级语言会需要更多的内存空间去存储内部状态、存储函数指针,按你这么说,现在的高级语言怕不是都要被喷
6 GB 内存和机械硬盘才是主要矛盾,因为内存的限制,你只能用外排序的类似思想去做统计 -话说需要压缩内存空间的话,为什么不写 C/C++- |
38
lance6716 2018-09-25 14:30:42 +08:00 via Android
|
39
nooper 2018-09-25 14:33:17 +08:00 2
hdf5, blosc. 10g 的能压缩成 1g 的内容。本人已测试。300m-> 20m-30m
|
40
skinny OP |
42
skinny OP @hahastudio 我知道高级语言会比 C 之类占用更多内存,我没有觉得有什么,一开始有心理准备,我粗糙的设计了下 C 的数据结构,预估了内存占用,然后看 pickle 文件和实际数据都不大,全部变成 Python 对象 collections.Counter[str, int]应该可以接受几倍的内存占用,当时我觉得 3GB 到 4GB 内存是可以搞定的,结果没想到爆了。我有考虑不周和偷懒的问题不存在,甚至还有穷的问题存在,不过一些人不知道他们到底在 diss 什么。
|
43
laike9m 2018-09-25 15:24:14 +08:00
如果 3kw 的 D[char[10],uint] 都要放进内存才能处理,是不是得考虑下算法的优化问题了
|
44
skinny OP @laike9m 实际是用 C 根本没问题,顶天了 600MB 左右(粗糙 dict 实现),因为实际数据才 400MB 左右,我吐槽的是内存占用,我根本不在乎快到几分钟内完成,只要在半小时内搞定,不影响我同时在进行的编码任务就行,只要不是过高的 CPU 使用率或是内存占用高到导致其它操作(如编码)不能正常进行就行。一开始我是觉得没问题才这样做的,要是考虑算法,我干嘛用 collections.Counter。
|
45
hahastudio 2018-09-25 15:38:40 +08:00
@skinny 我猜是因为开始很多人认为 pickle 就是直接把内存 dump 下来?
顺带一提,你是不是遇到了类似于这边的问题? https://stackoverflow.com/questions/16288936/how-do-i-prevent-memory-leak-when-i-load-large-pickle-files-in-a-for-loop |
46
lihongjie0209 2018-09-25 15:38:55 +08:00
@skinny 所以我说给一份测试数据然后大家自己跑一跑, 一直在这里说最后还有人怀疑你硬件有问题呢
|
47
skinny OP @hahastudio 刚刚验证了你发的那个链接,按那个解决方法试了,结果还是一样。实际上就是太多小对象,Python 对象底层数据结构又比较大。
|
48
skinny OP @lihongjie0209 追加里再次那么细致的说了数据类型、大小、数量、结构,眼神不好?你要不然按#28 楼说的用 range 生成一批数据测试,也没人说你,是不?
|
49
est 2018-09-25 16:09:49 +08:00 1
@skinny 你补充了那么多,比你第一次发帖的还长。你第一次发帖别人 1 楼注解回复了一句:不懂。
感受下。 好吧,我们说内存占用大的问题。一句话「 collections.Counter 数据总共 664MB 结果加载进去 6G 内存不够用」 不就完事了么。 非得说 Python 内存占用大。这和大多数人的经验相比而言是反直觉的。因为基本上能见到的 jvm 的应用起步 8G 内存。py 写的程序 200M 都算非常大的了。 |
50
est 2018-09-25 16:15:53 +08:00
@skinny 从你补充的信息来看, 大量 collections.Counter 数据做 plus 操作(就是合并?)是有额外的 copy 开销的。这里考虑用一些的 inline 的方式去优化。
你无论用什么语言都会遇到大 dict 合并问题,大 list 合并问题的。 |
51
est 2018-09-25 16:19:58 +08:00
其实最大的可能就是你反序列化之后的对象没有被 gc 掉。依然占着内存。看起来是 5 个 pickle 文件实际内存里存了好几份。
你试试 del 下那个对象。23333 或者你 pickle 有内存泄露。 |
52
2owe 2018-09-25 16:29:07 +08:00
强制使用 pickle protocol 高版本,pickle.HIGHEST_PROTOCOL ?只能说有改善,核心问题还是如你所知。
|
53
dbw9580 2018-09-25 16:31:30 +08:00
典型的又要马儿跑,又要马儿不吃草。
|
54
laqow 2018-09-25 16:38:21 +08:00 via Android
不用 Counter 和 pickle 不就完了吗
|
55
misaka19000 2018-09-25 16:52:22 +08:00
怎么感觉楼主好像在喷 Python ?
|
56
lihongjie0209 2018-09-25 16:53:31 +08:00
@skinny 知道这些信息并没有帮助, 写排序算法的时候也知道输入输出, 数据类型, 那么冒泡算法和归并算法就一样了? 你说 python 有什么问题的前提是你的代码要合理. 就你给的这些信息只够过过嘴瘾, diss python 而已, 并没有什么实际意义.
我已经说第三遍了, 给测试数据, 给需求, 大家都写不出来那是 python 的问题, 大家写的出来那是你的问题. |
57
wutiantong 2018-09-25 17:39:07 +08:00
楼主的不友善态度和杠精精神好像传染了我
我一个没学过 python 的花了点时间搜了一圈 google 又按照楼主的描述写了点测试,我后面贴一下 |
58
shm7 2018-09-25 17:40:28 +08:00
9 楼,大文件存储用 hdf5,h5py -> pytable 都可以用。
|
59
wutiantong 2018-09-25 17:43:15 +08:00 4
实际运行环境是新版 MBP,python3.7
``` import collections import pickle def make_cnt(section): cnt = collections.Counter() for i in range(6000000): cnt[str(i +6000000*section)] = i return cnt if __name__ == '__main__': cnt0 = make_cnt(0) pickle.dump(cnt0, open('/tmp/cnt0', 'wb')) input("Press Enter to continue...") cnt1 = make_cnt(1) pickle.dump(cnt1, open('/tmp/cnt1', 'wb')) input("Press Enter to continue...") cnt2 = make_cnt(2) pickle.dump(cnt2, open('/tmp/cnt2', 'wb')) input("Press Enter to continue...") cnt3 = make_cnt(3) pickle.dump(cnt3, open('/tmp/cnt3', 'wb')) input("Press Enter to continue...") cnt4 = make_cnt(4) pickle.dump(cnt4, open('/tmp/cnt4', 'wb')) input("Press Enter to continue...") ``` 这个代码主要是观察 Counter 的内存占用情况,观察结果是: 1. 一个 600 万条的 Counter 占用 900M 内存,平均每条记录占用 150 个字节,5 个这样的 Counter 总计占用内存 4.5G (个人觉得并不算很过分) 2. pickle 序列化后得到的文件是 130 多 M ``` import collections import pickle if __name__ == '__main__': cnt0 = pickle.load(open('/tmp/cnt0', 'rb')) input("Press Enter to continue...") cnt1 = pickle.load(open('/tmp/cnt1', 'rb')) input("Press Enter to continue...") cnt2 = pickle.load(open('/tmp/cnt2', 'rb')) input("Press Enter to continue...") cnt3 = pickle.load(open('/tmp/cnt3', 'rb')) input("Press Enter to continue...") cnt4 = pickle.load(open('/tmp/cnt4', 'rb')) input("Press Enter to continue...") ``` 这个代码主要是观察 pickle 反序列化过程中会不会产生额外的内存占用,以及反序列化出来的对象实际大小如何,观察结果是: 1. pickle 的反序列化过程有轻微的内存使用上涨但并不会产生内存泄漏 2. 反序列化出来的 Counter 略小于直接动态生成的 Counter,5 个 Counter 总计占用内存 4.3G 总结一下: 1. pickle 这个库挺不错的,压缩率和运算性能都很可观,而且也没观察到内存爆增或者内存泄漏的情况(至少在我的测试环境下是如此的) 2. 楼主所用的 Counter 每条记录占用 150 字节左右,总计应该是需要 4.5G 左右的内存,6G 内存应该是能撑得住的 3. 我猜楼主在后续的合并操作没有及时回收内存,故而需求了几乎翻倍的内存 |
60
sunhk25 2018-09-25 17:51:52 +08:00 via Android
|
61
hiths 2018-09-25 18:16:40 +08:00 via iPhone
楼主战斗力好强啊,顺便快来看一下楼上的答案吧。
|
62
skinny OP @wutiantong
你也可以完全不用 pickle 来测试,测试数据你可以简单先生成 3000 万条长度为 3-32 的 ascii printable 字符串(我这最长的一条有 95 个字节,不过非常非常少,多是 6 到 12 个字节的),重复数据条数占 24%,重复数据你随机插入,生成的字符串作为 K,V 你可以随机产生 1 到 2000 万之间的值,,生成测试数据要花时间,你也可以用更好的办法。 说实在的,我一开始就是吐槽 Python 对象内存占用大。 为了避免有人硬说内存泄露,你可以用如下代码(结果一样,内存需要非常多): ```python # Version: Python 3.6.6 x64 import collections import glob counter = collections.Counter() # 你也可以直接用 dict # counter = dict() for path in glob.glob(r'F:\TestData\*.txt'): with open(path, encoding='UTF-8') as input_stream: for line in input_stream: tmp = line.rstrip() k, v = tmp.rsplit('\t', maxsplit=1) c = int(v) del v del tmp counter[k] += c # n = counter.get(k, 0) # counter[k] = c + n ``` 我用.net core 按相似的方法实现了一遍,速度很快,内存占用 3GB: ```c# // .net core 2.1 // // Program.cs build options: Release, x64 using System; using System.Collections.Generic; using System.IO; using System.Text; namespace db_conv_cs { class Program { static void Main(string[] args) { Dictionary<string, uint> counter = new Dictionary<string, uint>(); string[] files = new string[] { @"F:\TestData\dat-1.txt", @"F:\TestData\dat-2.txt", @"F:\TestData\dat-3.txt", @"F:\TestData\dat-4.txt", @"F:\TestData\dat-5.txt" }; foreach (string path in files) { InsertItems(path, counter); } Console.WriteLine("{0} items", counter.Count); } static void InsertItems(string path, Dictionary<string, uint> counter) { FileStream file = new FileStream(path, FileMode.Open, FileAccess.Read); StreamReader reader = new StreamReader(file, Encoding.UTF8); string line = null; while ((line = reader.ReadLine()) != null) { line = line.TrimEnd('\r', '\n'); int i = line.LastIndexOf('\t'); if (i == 0) { continue; } string k = line.Substring(0, i); string v = line.Substring(i + 1); uint n = uint.Parse(v); uint c = 0; counter.TryGetValue(k, out c); counter[k] = c + n; } reader.Close(); file.Close(); } } } ``` |
63
skinny OP |
64
hotsymbol 2018-09-26 00:17:34 +08:00
Golang 了解一下?
|
65
lolizeppelin 2018-09-26 00:22:47 +08:00 via Android
python int 最少 28 字节 能不大么……
|
66
slixurd 2018-09-26 00:35:35 +08:00 1
本来 Python 的内存模型就设计成这样
内存占用大的飞起,比 Java 还大的多 这有什么好争的,看下对象的格式不就知道了.... |
67
zwh2698 2018-09-26 05:05:30 +08:00 via Android
在 @dychenyi 兄弟基础上给你补一句,windows 上叫 creatfilemapping,只要你愿意,TB 级别的都可以。
|
68
petelin 2018-09-26 07:24:49 +08:00 via Android
不是有人硬要说什么什么,是你的杆精。你说没泄露你程序就没泄露了?
人家给出来自己测试数据了,160MB 到内存里 4-5G,多清晰。你不能找着跑一遍看有没有问题?还逼逼了一堆不知道啥玩意,另外你的代码是真的丑,你引入一堆中间变量然后 del 干什么,链式调用不更优雅一点? |
69
skinny OP @slixurd 他们一些人是在捏造论点并攻击,没有一个跟我吐槽相关(推荐 hdf5 之类优秀库的除外),你反驳就是杠精、沟通能力、理解能力差,你说到底谁杠精、理解能力差?如果我一开始不说使用场景,他们要喷我什么也不说就瞎说,我说了又扣了个字眼说我不会用,回他们换成别的也可以,然后又说不给真实测试数据和代码,让他们随便塞按描述生成的那么 3000 万条到内存试试就成,range 总会用吧,我都不强求你怎么样了,然后又说我表达能力差。话说我跟他们兜什么圈子,内存占用、对象大小不是明摆着的么!跟杠精争什么!我本来就是吐个槽而已。
|
70
skinny OP @petelin 用 del 是免得和你这类杠精一样硬说有内存泄露。你要是还觉得有内存泄露你自己去写吧。那段代码怎么简单怎么来,免得优雅了你们又要说内存泄露。
|
71
kljsandjb 2018-09-26 08:07:15 +08:00 via iPhone
你需要跟 c 混编
|
72
jimisun 2018-09-26 08:13:04 +08:00 via Android
tomcat 路过
|
73
xrui 2018-09-26 08:17:13 +08:00 via Android
同感,之前整了个爬虫,想记录一下已访问过的网址。list.append (网址字符串),我看着任务管理器,每个网址大概消耗 1M 多内存。后来放弃了,写文件了
|
75
skinny OP @petelin 你们是不是扛得精神分裂,最后开始扛自己了。我标题就说得是 Python 太占内存,主贴里也是吐槽的这个,甚至描述都可以让你们生成数据测试。你们开始硬是说什么我不会用 pickle,然后又硬说 pickle 内存泄露,那人写了个测试说 pickle 没有泄露,然后我进一步遂了你们的心,压根儿不用 pickle,再次强调了数据生成和给了新的测试代码,你们照这个试试再杠?
|
77
lihongjie0209 2018-09-26 10:50:39 +08:00
@skinny 冒泡排序拿 C 写和拿 C#写差不了太多, 时间复杂度放在那里呢. 你要是指望拿汇编写出 O(nlgn)的冒泡排序那是你的问题. Python 对象占用空间当然比 C 大, 但是你代码设计合理吗, 你的代码完美到需要升级语言才能优化的地步? 我怀疑是你代码问题, 和 Python 没什么关系, 你又不提供代码, 又不提供测试数据, 只知道吐槽, 对你没有帮助, 对社区没有帮助.
|
78
lihongjie0209 2018-09-26 10:52:04 +08:00
@est 这个帖子很有意思
|
79
lihongjie0209 2018-09-26 10:56:53 +08:00
@xrui 你这是在开玩笑, 给代码, 给测试用例, 给 profile 然后再说一个网址可以占用 1M 内存
|
80
est 2018-09-26 11:46:57 +08:00
@lihongjie0209 大力出奇迹。
|
81
xrui 2018-09-26 11:53:32 +08:00
@lihongjie0209
不知这样杠精你可满意?任务管理器表面每 5 秒 python 内存使用增加 1M import requests import time from lxml import etree urls = ["https://movie.douban.com/subject/25820460/?from=subject-page"] visited=[] for i in range(100): try: url=urls[0] visited.append(url) urls.pop(0) data = requests.get(url).text s=etree.HTML(data) title=s.xpath('//*[@id="content"]/h1/span[1]/text()')[0] nextu=s.xpath('//*[@id="recommendations"]/div/dl[5]/dd/a/@href')[0] urls.append(nextu) time.sleep(5) except: print("sth") else: print(title) |
82
lihongjie0209 2018-09-26 12:49:20 +08:00
@xrui 我都不想说你, 自己看看代码写的什么鬼样
只爬取前 20 条: types | # objects | total size ==================================== | =========== | ============ <class 'str | 34273 | 4.89 MB <class 'dict | 4859 | 2.61 MB <class 'type | 1402 | 1.42 MB <class 'code | 9838 | 1.36 MB <class 'set | 1073 | 508.22 KB <class 'tuple | 4423 | 289.40 KB <class 'list | 2457 | 287.18 KB <class 'weakref | 2903 | 226.80 KB <class 'wrapper_descriptor | 2383 | 186.17 KB <class 'builtin_function_or_method | 2607 | 183.30 KB <class 'abc.ABCMeta | 146 | 145.60 KB <class 'getset_descriptor | 1873 | 131.70 KB <class 'int | 4203 | 125.74 KB <class 'method_descriptor | 1358 | 95.48 KB function (__init__) | 688 | 91.38 KB 美国队长 3 Captain America: Civil War 蚁人 Ant-Man 钢铁侠 Iron Man X 战警 X-Men 蜘蛛侠 Spider-Man 我,机器人 I, Robot 终结者 The Terminator 变形金刚 Transformers 我,机器人 I, Robot 终结者 The Terminator 变形金刚 Transformers 我,机器人 I, Robot 终结者 The Terminator 变形金刚 Transformers 我,机器人 I, Robot 终结者 The Terminator 变形金刚 Transformers 我,机器人 I, Robot 终结者 The Terminator 变形金刚 Transformers types | # objects | total size ==================================== | =========== | ============ <class 'str | 34427 | 5.27 MB <class 'dict | 4878 | 2.62 MB <class 'type | 1410 | 1.44 MB <class 'code | 9866 | 1.36 MB <class 'set | 1073 | 508.72 KB <class 'tuple | 4461 | 292.20 KB <class 'list | 2488 | 291.38 KB <class 'weakref | 2917 | 227.89 KB <class 'wrapper_descriptor | 2383 | 186.17 KB <class 'builtin_function_or_method | 2608 | 183.38 KB <class 'abc.ABCMeta | 146 | 147.05 KB <class 'getset_descriptor | 1878 | 132.05 KB <class 'int | 4216 | 126.14 KB <class 'method_descriptor | 1358 | 95.48 KB function (__init__) | 695 | 92.30 KB 爬取 20 条之后 str 的内存占用增加了 0.38M, 与你的描述: 每个网址大概消耗 1M 多内存 存在较大的差异, 需要你提供你的内存占用测试以及结果 计算内存占用的方法: from pympler import summary from pympler import muppy def print_mem(): summarize = summary.summarize(muppy.get_objects()) summary.print_(summarize) 参考文档: https://pythonhosted.org/Pympler/muppy.html#muppy |
83
lihongjie0209 2018-09-26 12:50:25 +08:00
@lihongjie0209 最开始的那句话发错了, 和本问题无关
|
85
leemove 2018-09-26 13:54:27 +08:00 2
小伙子敢吐槽 python 勇气可嘉.v 站只允许吐槽 js,php 辣鸡,python 是上等语言,上等语言的事能叫占用内存多吗?
|
86
lihongjie0209 2018-09-26 14:10:03 +08:00
@xrui
print_mem() l = [] for i in range(20): l.append("https://movie.douban.com/subject/25820460/?from=subject-page") # time.sleep(.5) print_mem() 自己测试一下完全只 append string 的内存占用, 几乎没有 你的内存上涨只可能是 python 的 gc 没有把 垃圾回收而已, 如果你需要准确控制垃圾回收, 那么自动 gc 的语言不适合你 |
87
lihongjie0209 2018-09-26 14:10:46 +08:00
@leemove 吐槽要有理有据, 瞎 BB 谁也会
|
88
newghost 2018-09-26 16:09:38 +08:00
Java 情何以堪
|
89
d18 2018-09-26 17:07:20 +08:00
成功钓出一群杠精?
|
90
firebroo 2018-09-26 18:54:37 +08:00
python 肯定大。。正常。https://github.com/firebroo/UnixTools/blob/master/uniq/hashtable.h 你说的粗糙的 c 的 hashmap,不能说是粗糙,这东西越精细内存占用越大,只能说精简。
|
91
clino 2018-09-26 21:42:44 +08:00
楼上你们贴代码怎么都不用 gist?特别是对于 python 这种缩进严格的语言...
|
92
jswangjieda 2018-09-27 09:43:16 +08:00
python 完全面向对象,包括 int,float 这种数字都是对象,内存占用更多好像也没啥奇怪的,原生 python 在性能上本来就不好,一般数据处理的话还是用 numpy 这种用 cython 写的库。拿 python 直接去和 java,c 之类的语言对比内存占用和运行速度本来就不对吧。
|
93
skinny OP @jswangjieda 我一开始没有直接去和 java,c 之类的语言对比,我开始说的是 Python 内存占用远远超过预估,所以吐槽了下 Python 内存占用太多(就这次的经验来看,大量小数据(超千万)不适合用标准库和内置容器对象)。可是炸出来一群杠精,所以才有后面别的语言的处理代码和结果。
@newghost Java 分配 3.5GB 内存可以搞定的,就是 CPU 使用率有点高。 |
94
skinny OP @clino 太麻烦,且主要是代码太简单。还有吐槽下主贴有支持 markdown,回复却不支持,还要删除回复全部行首空格。
|
96
jswangjieda 2018-09-27 10:10:51 +08:00
@skinny python 完全面向对象和动态类型的特性乍一看很美,但是对需要高性能的需求来说无异于是毒瘤,好在有 cython/numba 等库的支撑,不然 python 在科学计算上也不会这么好用
|
97
skinny OP @jswangjieda 估计等下要杠你了
|
98
jswangjieda 2018-09-27 10:42:05 +08:00
@skinny hahaha,没事没事,我只是说了我知道的事情,我本来就只拿 python 捣腾机器学习,其他方面又不懂,要是有人拿他们懂的东西来杠我,我也懒得回应
|