Performance enhancement of the turtle module
Ninguém assumiu esta issue ainda.
- Linguagem predominante
- Python
- Estrelas
- 77.2k
- Forks
- 36k
- Métricas de merge de PRs
- Métricas de PR pendentes
Descrição
Feature or enhancement
Proposal:
The original implementation of turtle.RawTurtle._goto:
def _goto(self, end):
"""Move the pen to the point end, thereby drawing a line
if pen is down. All other methods for turtle movement depend
on this one.
"""
## Version with undo-stuff
go_modes = ( self._drawing,
self._pencolor,
self._pensize,
isinstance(self._fillpath, list))
screen = self.screen
undo_entry = ("go", self._position, end, go_modes,
(self.currentLineItem,
self.currentLine[:],
screen._pointlist(self.currentLineItem),
self.items[:])
)
if self.undobuffer:
self.undobuffer.push(undo_entry)
start = self._position
if self._speed and screen._tracing == 1:
diff = (end-start)
diffsq = (diff[0]*screen.xscale)**2 + (diff[1]*screen.yscale)**2
nhops = 1+int((diffsq**0.5)/(3*(1.1**self._speed)*self._speed))
delta = diff * (1.0/nhops)
for n in range(1, nhops):
if n == 1:
top = True
else:
top = False
self._position = start + delta * n
if self._drawing:
screen._drawline(self.drawingLineItem,
(start, self._position),
self._pencolor, self._pensize, top)
self._update()
if self._drawing:
screen._drawline(self.drawingLineItem, ((0, 0), (0, 0)),
fill="", width=self._pensize) # ---- calls _drawline(), causing the time complexity to be O(n**2) ----
# Turtle now at end,
if self._drawing: # now update currentLine
self.currentLine.append(end)
if isinstance(self._fillpath, list):
self._fillpath.append(end)
###### vererbung!!!!!!!!!!!!!!!!!!!!!!
self._position = end
if self._creatingPoly:
self._poly.append(end)
if len(self.currentLine) > 42: # ---- hard-coded ----
self._newLine()
self._update() #count=True)
The hard-coded number 42 performs well on my Ubuntu, but it seriously lowers the frame rate of complicated turtle programs on Windows. According to my own FPS test, the number 320 performs best on Windows.
On the other hand, the TurtleScreenBase._drawline method:
def _drawline(self, lineitem, coordlist=None,
fill=None, width=None, top=False):
"""Configure lineitem according to provided arguments:
coordlist is sequence of coordinates
fill is drawing color
width is width of drawn line.
top is a boolean value, which specifies if polyitem
will be put on top of the canvas' displaylist so it
will not be covered by other items.
"""
if coordlist is not None:
cl = []
for x, y in coordlist: # ---- Repeats converting data ----
cl.append(x * self.xscale)
cl.append(-y * self.yscale)
self.cv.coords(lineitem, *cl)
if fill is not None:
self.cv.itemconfigure(lineitem, fill=fill)
if width is not None:
self.cv.itemconfigure(lineitem, width=width)
if top:
self.cv.tag_raise(lineitem)
The current time complexity is O(n**2). With some data preprocessed in _goto method, the performance can be further optimized.
From my perspective, the turtle module could be an excellent substitute for original tkinter.Canvas if it were optimized significantly.
Additionally, this proposal originally comes from my own project's source code.
Has this already been discussed elsewhere?
No response given
Links to previous discussion of this feature:
No response
Guia de contribuição
Primeiros passos
- Leia a issue inteira e depois o guia de contribuição do projeto.
- Comente na issue dizendo que vai assumir — evita que duas pessoas façam o mesmo trabalho.
- Faça um fork do repositório e trabalhe em uma branch.
- Abra um pull request que referencie o número da issue.
Direção de pesquisa
Revise turtle.RawTurtle._goto e TurtleScreenBase._drawline, concentrando-se nas atualizações repetidas de linhas e na conversão de coordenadas descritas na proposta. Estabeleça um benchmark representativo de FPS em várias plataformas e verifique se qualquer otimização preserva o desenho, a ação de desfazer e o comportamento da tartaruga. Considera-se concluído quando houver uma melhoria de desempenho mensurável sem regressões.
Escrita pelo modelo de indexação a partir do texto da issue.
Avaliação
- Stack de tecnologia
- python
- Domínio
- performance
- Tipo de issue
- Funcionalidade
- Dificuldade
- 5/5
- Tempo estimado
- Mais de uma semana
- Status de atividade
- Estagnada
- Clareza
- Razoavelmente clara
- Facilidade para iniciantes
- 35/100