Drawing lines / `add_shape()` is very slow, possible quadratic Schlemiel the Painter algorithm
Nadie ha tomado este issue todavía.
- Lenguaje dominante
- Python
- Estrellas
- 18.8k
- Forks
- 2.8k
- Merge medio
- 16 h 26 min
- PR fusionados (30 d)
- 21
Descripción
To reproduce: Create lines.py as follows:
import plotly.graph_objects as go
import plotly.express as px
import time
import random
N = [50, 100, 200, 400, 800]
def plot_random_lines(n):
fig = go.Figure()
for i in range(n):
c = [random.random() for _ in [0, 1, 2, 3]]
fig.add_shape(type='line', x0=c[0], y0=c[1], x1=c[2], y1=c[3])
# We don't show the figure to avoid any possible influence from the
# graphics driver.
def timings():
t_cum = []
for n in N:
t0 = time.process_time_ns()
plot_random_lines(n)
t_cum.append((time.process_time_ns() - t0) / 1e6)
t_per_line = [t/n for (t, n) in zip(t_cum, N)]
fig1 = px.scatter(x=N, y=t_cum, labels={'x': 'Number of lines', 'y': 'Cumulative time [ms]'})
fig1.show()
fig2 = px.scatter(x=N, y=t_per_line, labels={'x': 'Number of lines', 'y': 'Time per line [ms]'})
fig2.show()
timings()
Install plotly and run the above example.
- Expected: Draws the lines in a few milliseconds
- Actual: It takes more than half a minute on a modern MacBook
Notice that the time per line increases linearly with the number of lines drawn.
This looks like a classic example of a Schlemiel the painter algorithm, candidate for
Joel Spolsky's collection.
Observations
I suspect that the following code locations are related to the bug.
- In https://github.com/plotly/plotly.py/blob/master/packages/python/plotly/plotly/basedatatypes.py#L5310,
curr_valincreases in length with each call toadd_shape(). - In https://github.com/plotly/plotly.py/blob/master/packages/python/plotly/_plotly_utils/basevalidators.py#L2553,
vincreases in length with each call.
Guía de contribución
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Línea de trabajo
Comienza con packages/python/plotly/plotly/basedatatypes.py alrededor de la línea 5310 y packages/python/plotly/_plotly_utils/basevalidators.py alrededor de la línea 2553; después, ejecuta la reproducción lines.py proporcionada. Comprueba cómo crecen los valores a lo largo de llamadas repetidas a add_shape(). La tarea estará terminada cuando dibujar muchas líneas ya no muestre un tiempo por línea que aumente linealmente y se complete en milisegundos, como se espera.
Escrito por el modelo de indexación a partir del texto del issue.
Evaluación
- Stack tecnológico
- python
- Área
- data-visualization, performance
- Tipo de issue
- Error
- Dificultad
- 4/5
- Tiempo estimado
- 3-5 días
- Estado de actividad
- Estancado
- Claridad
- Bastante claro
- Aptitud para principiantes
- 45/100