Python 链表的内存优化
我最近制作了一个脚本,使用一个自定义迷宫类,从几个迷宫节点生成随机迷宫。每个节点如下所示:Python 链表的内存优化,python,python-3.x,out-of-memory,Python,Python 3.x,Out Of Memory,我最近制作了一个脚本,使用一个自定义迷宫类,从几个迷宫节点生成随机迷宫。每个节点如下所示: class mazeNode: def __init__(self, pos, conn = None): self.pos = pos if conn: self.conns = [conn] else: self.conns = [] conn是另一个mazeNode对象,并且在创建迷宫期间更改s
class mazeNode:
def __init__(self, pos, conn = None):
self.pos = pos
if conn:
self.conns = [conn]
else:
self.conns = []
conn
是另一个mazeNode对象,并且在创建迷宫期间更改self.conn
,以包括节点连接到的每个mazeNode对象pos
是一个带有节点位置的元组。创建迷宫时,将创建迷宫节点对象,并根据深度优先搜索算法以分支方式链接在一起
这个脚本工作得非常好,可以在大约10秒内创建一个500*500大小的迷宫。然而,它似乎不是非常有效的内存。我已经设法创建了一个6000*6000大小的迷宫,但是当我尝试10000*10000时,无论我做什么,我都会得到一个内存错误,即使我分配了50GB的虚拟RAM。对于这个尺寸,我最终得到了10^8个mazeNode对象
我尝试使用shelve
模块,但这会使脚本速度过慢,无法使用,对于更大的迷宫,我得到了一个递归深度错误(可能是由于不必要的递归,脚本速度太慢)
我想知道是否有任何方法可以优化脚本的内存使用,同时保持速度。所有节点都链接在一起,但它们不一定都在RAM中
编辑
迷宫课程如下:
class Maze:
def __init__(self, xSize, ySize):
self.pos = (xSize//2, ySize//2)
self.xSize = xSize
self.ySize = ySize
self.directions = [(0, 1), (1, 0), (0, -1), (-1, 0)]
self.visit = set([self.pos])
self.maze = mazeNode(self.pos)
self.node = self.maze
self.stack = Stack()
self.deadEnds = 0
for i in randPerm(list(range(4))):
self.stack.put(mazeNode(add(self.pos, self.directions[i]), self.node))
def makeMaze(self):
while True:
while self.node.pos in self.visit and not self.stack.isEmpty():
self.node = self.stack.pop()
if self.stack.isEmpty():
break
if self.node.pos not in self.visit:
self.visit.add(self.node.pos)
for conn in self.node.conns:
conn.conns.append(self.node)
tempCount = 0
for i in randPerm(list(range(4))):
pos = add(self.node.pos, self.directions[i])
if pos not in self.visit and check(pos, self.xSize, self.ySize):
self.stack.put(mazeNode(pos, self.node))
tempCount += 1
if tempCount == 0:
self.deadEnds += 1
if len(self.maze.conns) == 1:
self.deadEnds += 1
编辑2:
我使用了slot:并对mazeNode类进行了如下编辑:
class mazeNode:
__slots__ = ('posx', 'posy', 'conns', )
def __init__(self, pos, conn = None):
self.posx = pos[0]
self.posy = pos[1]
self.conns = [conn] if conn else []
并使用sys.getsizeof()
获取类实例的大小
print(sys.getsizeof(self.maze), sys.getsizeof(self.maze.posx), sys.getsizeof(self.maze.posy), sys.getsizeof(self.maze.conns))
打印642896
。但是,如果我删除\uuuu插槽
,我会得到562896
,这似乎很奇怪。我该如何解释呢?\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
class MazeNode(object):
__slots__ = ('pos', 'conn', )
def __init__(self, pos, conn=None):
self.pos = pos
self.conns = [conn] if conn else []
唯一需要记住的是,时隙类型/类不能动态添加属性。只能设置和/或修改中列出的属性。即使它们确实显著减少了每个对象的内存使用,也不要发疯,为您定义的每个类定义插槽。明智地使用它们。请您也提供实际生成迷宫的代码好吗?另外,作为旁注,if语句可以是self.conns=[conn]if conn else[]
您试过使用吗?这至少可以减少每个对象的内存使用量。我绝对建议使用\uuuuuu slots\uuuuu
,因为如果有10**8个对象,即使删除一个字节的内存分配也会节省100MB的内存@xj9有最好的主意here@xj9我还没有听说过\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
,但乍一看,它可能会有很大帮助。谢谢我就是这么做的,看我最后的编辑。然而,我的结果并不是我所希望的。