Drawing lines / `add_shape()` is very slow, possible quadratic Schlemiel the Painter algorithm

Offen
#3,620 2 Kommentare 6 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen

Dieses Issue hat noch niemand übernommen.

Bewertung

Schwierigkeit
4/5
Geschätzter Aufwand
3-5 Tage
Anfängerfreundlichkeit
45/100
Issue-Typ
Bug
Klarheit
Größtenteils klar
Aktivitätsstatus
Veraltet
Tech-Stack
python

Rechercherichtung

Beginne mit packages/python/plotly/plotly/basedatatypes.py ungefähr bei Zeile 5310 und packages/python/plotly/_plotly_utils/basevalidators.py ungefähr bei Zeile 2553 und führe dann die bereitgestellte lines.py-Reproduktion aus. Prüfe, wie die Werte über wiederholte Aufrufe von add_shape() hinweg wachsen. Erledigt ist die Aufgabe, wenn das Zeichnen vieler Linien nicht mehr zu einer linear zunehmenden Zeit pro Linie führt und wie erwartet in Millisekunden abgeschlossen wird.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Beschreibung

P2 performance

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.

Vorherrschende Sprache
Python
Sterne
18.8k
Forks
2.8k
Ø Merge
16 Std. 26 Min.
Gemergte PRs (30 T.)
21

Beitragsleitfaden

Beitragsleitfaden öffnen

Erste Schritte

  1. Lesen Sie das ganze Issue und danach den Beitragsleitfaden des Projekts.
  2. Schreiben Sie ins Issue, dass Sie es übernehmen — das erspart doppelte Arbeit.
  3. Forken Sie das Repository und arbeiten Sie in einem Branch.
  4. Öffnen Sie einen Pull Request, der die Issue-Nummer nennt.

Mehr aus plotly/plotly.py

Alle Issues in plotly/plotly.py

Ähnliche Issues

Weitere Issues zu Python

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.