关于读写文件执行速度

2021-04-14 21:01:56 +08:00
 Virace
代码不好贴, 因为涉及到很多个文件

简单就是:
读取 A 类 文件, 根据偏移量提取出 B 类文件, 解析 B 类文件中的数据.

A 类文件中有可能有多个 B 类文件.
A 类文件几十兆, B 类文件几兆.
B 类文件是不写入本地的, 直接解析.



大概有接近 1000 个 A 类文件, 随着循环时间越来越长, 解析 B 类文件数据的这个函数执行会越来越慢.
多数使用过的变量 都有手动用 del 删除


每次循环 A 文件前 关闭 gc, A 文件使用后开启 gc 手动调用 gc.collect()

随着循环次数变多, 解析 B 类文件的函数, 就会从最开始的几十毫秒到后来的几秒甚至时间更长.

占用内存波动不大, 一直是 300M 左右
1799 次点击
所在节点    Python
26 条回复
imn1
2021-04-14 21:14:17 +08:00
那就加大内存使用量,A 全部读入内存后关闭
Virace
2021-04-14 21:19:46 +08:00
@imn1 还是内存的事么, 测试机内存倒是够用, 实际是要在一个 运行内存只有 1G 的机器上运行. = =
liprais
2021-04-14 21:26:04 +08:00
解析完了记下来不就完了
abersheeran
2021-04-14 21:29:06 +08:00
根据偏移量直接读文件某一部分这事可以先上 mmap 优化一下看看。另外你这个确定是慢在解析上吗?是不是内存超限了导致系统自动分配虚拟内存给你,疯狂交换虚拟内存页导致的。我以前遇到过类似问题。你可以先排查一下。
westoy
2021-04-14 21:30:22 +08:00
不要管程序吃多少内存

跑的时候观察下吃 swap 没有

你不停做文件读写, 等于不停触发 linux 的文件缓存机制,linux 也不是彻底没内存才会触发 swap

swap 占用不停变化的话, 直接禁用或者调整内核的 vm.swapiness
Virace
2021-04-14 21:38:44 +08:00
@abersheeran 对只是慢在解析上, 简单的装饰器计算运行时间的. 测试是在 win 环境下出现的.
clino
2021-04-14 21:39:22 +08:00
"随着循环次数变多, 解析 B 类文件的函数, 就会从最开始的几十毫秒到后来的几秒甚至时间更长."
是解析本身的耗时越来越长吗?不太理解这是什么导致的。
Virace
2021-04-14 21:39:55 +08:00
@westoy 测试是在 win 环境下出现的. 也会有类似的情况嘛.
abersheeran
2021-04-14 21:42:34 +08:00
@Virace Windows 也有虚拟内存的。先排查这个情况再考虑其他的。任何语言都不会因为整个程序的内存占用变多而运算变慢的。出现这情况大概率是虚拟内存的锅。
geelaw
2021-04-14 21:44:30 +08:00
为什么你要关掉 GC ?
Virace
2021-04-14 21:52:50 +08:00
@geelaw 经过测试在读入文件后 关闭 GC 执行后续操作 操作完毕在打开 GC 手动清理, 比平常要快. 意思就是如果不关闭的话, 这种越运行越慢的问题会更严重
crclz
2021-04-14 22:06:44 +08:00
建议楼主把代码贴出来,给大家一个最小的可重现的代码,既方便大家调试,也方便排除其他问题。
还有就是楼主一些地方的表述不太清晰,可能会让项目成员以外的路人产生困惑。例如“随着循环时间越来越长, 解析 B 类文件数据的这个函数执行会越来越慢”
crclz
2021-04-14 22:07:53 +08:00
还有一个建议:用某种 profiler 看看到底哪些函数是罪魁祸首,方便定位问题
Virace
2021-04-14 22:18:19 +08:00
代码不好贴, 解析的意思, B 类文件是个独有个格式, 经过几个循环能完全读完. 将读完的数据保存到本地. 这是这个解析函数要做的. 确实用 pycharm 的 profiler 运行了一下, 显示 76%的时间都在这个解析函数上.
keakon
2021-04-14 22:32:50 +08:00
如果解析的文件是 json 的话,市面上所有的 json 库都会内存泄露
Virace
2021-04-14 22:35:58 +08:00
@keakon 解析倒不是, 解析完毕保存的数据是 json.
clino
2021-04-14 22:44:44 +08:00
你说解析函数有误导性,看起来其实这个函数不光做了解析还干了很多其他的事情,这里面有很多细节和可能性。
我的建议是仔细研究这个函数,看到底越来越慢是这个函数的哪一步导致的,如果能找到,那大概率能猜出是什么导致越来越慢。
xiaoming1992
2021-04-14 22:54:18 +08:00
笨办法,把那个解析函数按照二分法,移除掉一部分功能后再运行试试
Virace
2021-04-14 23:00:41 +08:00
@clino 用 profiler 工具找出了一个运行比较长的函数, 已经贴到附言上了
wuwukai007
2021-04-14 23:42:51 +08:00
要不用 pysnooper 逐行分析一下?

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

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

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

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

© 2021 V2EX