我正在尝试优化我的库的方法,该方法用于我的不和谐机器人 但我不知道如何优化这个方法。 该方法主要是进行字符串操作来渲染字符串 它有 2 维,就像旧游戏中仅由角色组成的一样。
我正在考虑使用 Numba 和 Numpy 之类的东西 但似乎不支持这种方法。 那么我的情况应该怎么办呢?
这是我写的代码:
def render(self, is_string=True):
"""
Returns the rendered canvas as a string if "is_string" is true else as a 2D-list
"""
line = self.canvas_owner.void * self.size["x"] + "\n"
rows = list(self.row_render_dict.keys())
rows.sort()
canvas = ""
number_of_row_to_render = len(self.row_render_dict)
last_row = 0
if len(rows) == 0:
# nothing to render
canvas = line * self.size["y"]
return canvas
else:
last_row = rows[0]
canvas += line * (rows[0]) # adds line before the first one
for todo_row in rows:
number_to_fill_up = todo_row - 1 - last_row
if number_to_fill_up > 0:
canvas += line * number_to_fill_up
last_row = todo_row
x_to_render_line = list(self.row_render_dict[todo_row].keys())
x_to_render_line.sort()
render_line = ""
sprites_to_render = len(x_to_render_line)
items_rendered = 0 # also includes void
# todo_line is the character position that gets rendered
for todo_line in x_to_render_line:
# fill up with "void" until something to render
number_to_fill_up = (todo_line - items_rendered)
if number_to_fill_up > 0:
# if there is something that can be filled up
render_line += self.canvas_owner.void * number_to_fill_up
items_rendered += number_to_fill_up
row_dict = self.row_render_dict[todo_row]
render_line += row_dict[todo_line][0].char
items_rendered += 1
sprites_to_render -= 1
if sprites_to_render == 0:
# if nothing else to render on this line we fill up the line with "void"
number_to_fill_up = self.size["x"] - (todo_line + 1)
render_line += self.canvas_owner.void * number_to_fill_up + "\n"
items_rendered += number_to_fill_up
canvas += render_line
break
number_of_row_to_render -= 1
if number_of_row_to_render <= 0:
# prob not here
number_to_fill_up = self.size["y"] - todo_row - 1
canvas += line * number_to_fill_up
break
return canvas
所以有几种方法可以优化你的脚本:
1 - 最小化字符串连接:字符串连接 (+=) 可能会很慢,尤其是在循环内,因为记住字符串在 Python 中是不可变,并且每次连接都会创建一个新的 str。因此,尝试使用列表来累积画布的各个部分,然后在最后将它们连接起来。
2 - 使用局部变量:重复访问 self.size["x"] 或 self.canvas_owner.void 等属性可能会很慢。在进入循环之前将它们存储在局部变量中。
3 - 循环优化:您可以使用sorted()函数来代替list.sort()。它返回一个新列表,对于您的用例来说可能会更快。
4-字典访问优化;在内部循环中,您多次访问字典键。您可以通过在循环之外获取字典值来优化它。
5 - 预分配内存:如果您知道要创建的最终字符串的大小,最好为其预分配内存,而不是在连接时重复调整字符串大小...
6 - 提前退出条件:某些循环具有在循环完成之前可以满足的条件。如果可能的话,使用它来尽早打破循环。