图像生成速度慢
Slow image generation
我对 python 比较陌生,我构建了一个 Tower of Hanoi 求解器,它将解决方案打印为图像 (https://en.wikipedia.org/wiki/Tower_of_Hanoi)
它按预期工作,但生成图像非常慢。
代码如下:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import argparse
from PIL import Image
def hanoi(disks, source, helper, target, steps):
if disks > 0:
hanoi(disks - 1, source, target, helper, steps)
target.append(source.pop())
steps.append([SOURCE[:], HELPER[:], TARGET[:]])
hanoi(disks - 1, helper, source, target, steps)
def save_image(name):
print('\nSaving image {}.png'.format(name))
data = []
peg = args.disks * 2
cells = peg * 3 + 40 # 40 is to put some spaces between pegs and the border
for step in steps:
for _ in range(5): # White space
data.append([1 for _ in range(cells)])
src = step[0]
hlp = step[1]
trg = step[2]
size = max(len(src), len(hlp), len(trg))
for _ in range(size - len(src)):
src.append(0)
for _ in range(size - len(hlp)):
hlp.append(0)
for _ in range(size - len(trg)):
trg.append(0)
src.reverse()
hlp.reverse()
trg.reverse()
for s, h, t in zip(src, hlp, trg):
blanksrc = peg - 2 * s
blankhlp = peg - 2 * h
blanktrg = peg - 2 * t
row = [1 for _ in range(10)]
row += [1 for _ in range(blanksrc // 2)]
row += [0 for _ in range(s * 2)]
row += [1 for _ in range(blanksrc // 2)]
row += [1 for _ in range(10)]
row += [1 for _ in range(blankhlp // 2)]
row += [0 for _ in range(h * 2)]
row += [1 for _ in range(blankhlp // 2)]
row += [1 for _ in range(10)]
row += [1 for _ in range(blanktrg // 2)]
row += [0 for _ in range(t * 2)]
row += [1 for _ in range(blanktrg // 2)]
row += [1 for _ in range(10)]
data.append(row)
for _ in range(5):
data.append([1 for _ in range(cells)]) # White space
data.append([0 for _ in range(cells)]) # Black line to separate steps
da = [bit for row in data for bit in row]
image = Image.new('1', (cells, len(data)))
image.putdata(da)
image.save('{}.png'.format(name))
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('-d', '--disks', type=int, default=4,
help='Number of disks, default 4')
parser.add_argument('-f', '--filename', help='Filename', required=True)
args = parser.parse_args()
if not args.disks > 0:
raise ValueError('There must be at least one disk')
SOURCE = list(reversed(range(1, args.disks + 1)))
TARGET = []
HELPER = []
steps = [[SOURCE[:], HELPER[:], TARGET[:]]]
hanoi(args.disks, SOURCE, HELPER, TARGET, steps)
save_image(args.filename)
如前所述,生成图像需要很长时间。
我怎样才能让它更快,为什么它这么慢?
谢谢
用于生成图像的块在 for 循环中。取消缩进,然后将执行时间除以 3。其余的(在我的旧桌面上是 0.04 秒,不是那么长)是 PIL 导入开销。我认为唯一更快的方法是使用 ppm 图像格式(但它会提供巨大的文件)而不是使用 PIL。无论如何,你还是应该听听@PixelEinstein 的建议,试试codereview
我对 python 比较陌生,我构建了一个 Tower of Hanoi 求解器,它将解决方案打印为图像 (https://en.wikipedia.org/wiki/Tower_of_Hanoi)
它按预期工作,但生成图像非常慢。
代码如下:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import argparse
from PIL import Image
def hanoi(disks, source, helper, target, steps):
if disks > 0:
hanoi(disks - 1, source, target, helper, steps)
target.append(source.pop())
steps.append([SOURCE[:], HELPER[:], TARGET[:]])
hanoi(disks - 1, helper, source, target, steps)
def save_image(name):
print('\nSaving image {}.png'.format(name))
data = []
peg = args.disks * 2
cells = peg * 3 + 40 # 40 is to put some spaces between pegs and the border
for step in steps:
for _ in range(5): # White space
data.append([1 for _ in range(cells)])
src = step[0]
hlp = step[1]
trg = step[2]
size = max(len(src), len(hlp), len(trg))
for _ in range(size - len(src)):
src.append(0)
for _ in range(size - len(hlp)):
hlp.append(0)
for _ in range(size - len(trg)):
trg.append(0)
src.reverse()
hlp.reverse()
trg.reverse()
for s, h, t in zip(src, hlp, trg):
blanksrc = peg - 2 * s
blankhlp = peg - 2 * h
blanktrg = peg - 2 * t
row = [1 for _ in range(10)]
row += [1 for _ in range(blanksrc // 2)]
row += [0 for _ in range(s * 2)]
row += [1 for _ in range(blanksrc // 2)]
row += [1 for _ in range(10)]
row += [1 for _ in range(blankhlp // 2)]
row += [0 for _ in range(h * 2)]
row += [1 for _ in range(blankhlp // 2)]
row += [1 for _ in range(10)]
row += [1 for _ in range(blanktrg // 2)]
row += [0 for _ in range(t * 2)]
row += [1 for _ in range(blanktrg // 2)]
row += [1 for _ in range(10)]
data.append(row)
for _ in range(5):
data.append([1 for _ in range(cells)]) # White space
data.append([0 for _ in range(cells)]) # Black line to separate steps
da = [bit for row in data for bit in row]
image = Image.new('1', (cells, len(data)))
image.putdata(da)
image.save('{}.png'.format(name))
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('-d', '--disks', type=int, default=4,
help='Number of disks, default 4')
parser.add_argument('-f', '--filename', help='Filename', required=True)
args = parser.parse_args()
if not args.disks > 0:
raise ValueError('There must be at least one disk')
SOURCE = list(reversed(range(1, args.disks + 1)))
TARGET = []
HELPER = []
steps = [[SOURCE[:], HELPER[:], TARGET[:]]]
hanoi(args.disks, SOURCE, HELPER, TARGET, steps)
save_image(args.filename)
如前所述,生成图像需要很长时间。
我怎样才能让它更快,为什么它这么慢?
谢谢
用于生成图像的块在 for 循环中。取消缩进,然后将执行时间除以 3。其余的(在我的旧桌面上是 0.04 秒,不是那么长)是 PIL 导入开销。我认为唯一更快的方法是使用 ppm 图像格式(但它会提供巨大的文件)而不是使用 PIL。无论如何,你还是应该听听@PixelEinstein 的建议,试试codereview