【问题标题】:high RAM usage by eval function in python [duplicate]python中eval函数的高RAM使用率[重复]
【发布时间】:2020-11-30 10:34:43
【问题描述】:

我将每行 1(不是第 0 行)实现为来自 2 个文件(第一个 ~30MB 和第二个 ~50MB)的字符串,其中第 0 行只有一些我不需要 atm 的信息。第 1 行是一个字符串数组,其中包含大约 1.3E6 个较小的数组,例如 ['I1000009', 'A', '4024', 'A'] 作为信息。

[[['I1000009', 'A', '4024', 'A'], ['I1000009', 'A', '6734', 'G'],...],[['H1000004', 'B', '4024', 'A'], ['L1000009', 'B', '6734', 'C'],...],[and so on],...]

两个文件都以相同的方式填充。这就是文件大小在 30 到 50MB 之间的原因。我用我的 .py 脚本读取了这些文件,以访问我需要的单个信息:

import sys

myID        = sys.argv[1]
otherID     = sys.argv[2]

samePath        = '/home/srv/Dokumente/srv/' 
FolderName      = 'checkArrays/'
finishedFolder  = samePath+'finishedAnalysis/'
myNewFile       = samePath+FolderName+myID[0]+'/'+myID+'.txt'
otherFile       = samePath+FolderName+otherID[0]+'/'+otherID+'.txt'
nameFileOKarray = '_array_goodData.txt'

import csv 
import os 
import re #for regular expressions
# Text 2 - Start
import operator # zum sortieren der csv files
# Text 2 - End

whereIsMyArray    = 1
text_file         = open(finishedFolder+myID+nameFileOKarray, "r")
line              = text_file.readlines()[whereIsMyArray:];
myGoodFile        = eval(line[0])
text_file.close()

text_file         = open(finishedFolder+otherID+nameFileOKarray, "r")
line              = text_file.readlines()[whereIsMyArray:];
otherGoodFile     = eval(line[0])
text_file.close()

print(str(myGoodFile[0][0][0]))
print(str(otherGoodFile[0][0][0]))

我的问题是,如果我在 shell 上启动我的 .py 脚本:

python3 checkarr_v1.py 44 39

我的 4GB pi 服务器的 RAM 增加到 RAM 的限制并交换并死掉。然后我尝试在 32Gb RAM 服务器上启动 .py 脚本并查看它是否有效,但 RAM 的使用量确实很大。看图片

(松弛模式)RAM和CPU的正常使用概述: slackmode

(startsequence) RAM ~6GB 和 CPU 最高使用率概览:highest point

然后它会在约 1 分钟后上下波动:1.2Gb 到 3.6Gb,然后到 1.7Gb,然后到 1Gb,然后脚本完成约 1 分钟并显示正确的输出。

您能否帮助我了解是否有更好的方法来解决 4Gb 覆盆子 pi 的问题?这是编写 2 个文件的更好方法吗,因为 [",] 符号在文件中也有空格?这是一个更好的解决方案,因为 eval 函数是将字符串实现为数组吗?我不明白为什么 80MB 文件将 RAM 增加到 6Gb 左右。这听起来我做错了什么。br thx

【问题讨论】:

  • 您不能在 50 MB 的文本文件中包含 1.3E9 个项目。即使每个元素只有 1 个字节加上一个逗号,也就是 2.6GB。
  • @MauriceMeyer 非常感谢。这很有帮助。也许我必须重新考虑我使用 python 的概念
  • @ThomasWeller 我不知道你在计算什么,但我有一个 50Mb 的文件,其中包含 1.3E9 ['fist','A','B','C'] 数组信息。
  • 1E3 是 1000 或 k,1E6 是 1000*1000 或一百万或 M,1E9 是 1000*1000*1000 或十亿或 G。要么是误解,要么你有一个 NTFS 压缩文件和您正在查看压缩文件的大小。
  • @ThomasWeller 当然......现在我看到了我的失败。 1.3E6 不是 9. sry :)

标签: python unix


【解决方案1】:

如果您将其读入应用程序,无论您做什么,1.3E9 数组都会有很多字节。

我不知道您的代码是否执行了您真正想做的事情,但您只使用了第一个数据项。如果这就是您想要做的,那么不要阅读整个文件,只需阅读第一部分。

而且:我建议不要使用“eval”来反序列化数据。 内置的json 模块将以几乎相同的格式提供数据(如果您控制输入格式)。

不过,最后:如果您想在程序中保存这么多数据,那么您会看到很多 GB 的内存使用量。

如果您只是想处理它,我会采取更多迭代的方法,每次做一点,而不是吞下整个文件。尤其是在资源有限的情况下。

更新:我现在看到它是 1.3e6,而不是 1.3e9 条目。巨大差距。 :-) 那么json数据应该没问题。在我的机器上,1.3M ['RlFKUCUz', 'A', '4024', 'A'] 的列表大约需要 250MB。

【讨论】:

  • 1.) 代码完成了它必须做的事情。它的作用并不是很壮观。 2)“使用第一个数据项”是什么意思?如果您只想读取该字符串的前 200 部分并将该部分转换为数组,那么忘记它!我需要孔数组将其与 mysql 数据库进行比较。 3)感谢json链接。认为这就是原因。我认为那个 eval 函数有问题。大谢谢! 4) 是的,我认为我需要非常多 GB 的 RAM 才能同时为 100 多个用户执行此操作 5) 使用我不理解的迭代方法。举个例子?
  • @user2 2.) myGoodFile[0][0][0] 似乎只访问第一个数据。 5.) 迭代方法意味着一次读取一点,而不是一次将所有内容加载到内存中。例如,如果您有不同的文件布局,其中每个“节”为一行,您可以轻松地一次处理一行,然后将其丢弃。这样您就不需要一次将所有数据保存在内存中。
  • 您的意思是每行都有自己的数组,例如 [['RlFKUCUz', 'A', '4024', 'A'],['2', 'A', '4111' , B'],['bla', 'X', '4024', 'C'], ....] 其中只有 A 的数组用于一行,B 用于另一行,依此类推?那么我可以有 50k 到 70k 之间的一条线,而不是全部。这是一个机会,但我想我会先尝试那个 JSON 技巧。也许它有效,但首先我必须弄清楚如何做到这一点并重写我的大部分旧代码。谢谢你和@MauriceMeyer。我有第二条路
猜你喜欢
  • 1970-01-01
  • 2018-11-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-20
  • 2013-11-23
相关资源
最近更新 更多