Lassen Sie mich versuchen, das Problem ein wenig mehr zu skizzieren.
Sie haben eine Oberfläche, auf die Sie Punkte und Linien zeichnen können, und Sie wissen, wie Sie es aussehen lassen, wie Sie es aussehen möchten.
Sie verfügen über eine Datenquelle mit Punkten, die gezeichnet werden können, und diese Datenquelle wird im laufenden Betrieb geändert.
Sie möchten, dass die Oberfläche die eingehenden Daten so genau wie möglich widerspiegelt.
Die erste Frage ist - was ist mit Ihrer Situation ist langsam? Weißt du, woher deine Verspätungen kommen? Stellen Sie zuerst sicher, dass Sie ein Problem zu lösen haben; Zweitens, stellen Sie sicher, dass Sie wissen, woher Ihr Problem kommt.
Angenommen, Ihr Problem in der Größe der Daten, die Sie bedeuten. Wie man das anspricht, ist eine komplexe Frage. Es hängt von den Eigenschaften der Daten ab, die grafisch dargestellt werden - welche Invarianten Sie annehmen können und so weiter. Sie haben über das Speichern von Daten in einer float[]
gesprochen, also gehe ich davon aus, dass Sie eine feste Anzahl von Datenpunkten haben, die sich im Wert ändern. Ich gehe auch davon aus, dass mit "100 oder 1000", was du meintest, "viele und viele" gemeint waren, denn ehrlich gesagt, 1000 Floats sind einfach nicht viele Daten.
Wenn Sie ein wirklich großes Array zu ziehen, wird Ihre Leistungsgrenze schließlich von looping über das Array kommen. Ihre Leistungsverbesserung wird dann reduzieren, wie viel von dem Array Sie durchlaufen. Hier kommen die Eigenschaften der Daten ins Spiel.
Eine Möglichkeit, das Volumen des Ankonstruktion zu reduzieren, ist eine ‚schmutzige Liste‘ zu halten, die wie ein Queue<Int>
wirkt. Jedes Mal, wenn sich eine Zelle in Ihrem Array ändert, reihen Sie diesen Array-Index in die Warteschlange ein und markieren ihn als "dreckig". Jedes Mal, wenn die Zeichenmethode erneut aufgerufen wird, wird eine feste Anzahl von Einträgen aus der Liste gelöscht und nur der Teil des gerenderten Bilds aktualisiert, der diesen Einträgen entspricht. Sie müssen wahrscheinlich etwas Skalierung und/oder Kantenglättung durchführen etwas, denn mit so vielen Datenpunkten haben Sie wahrscheinlich mehr Daten als Bildschirmpixel. Die Anzahl der Einträge, die Sie bei einem gegebenen Frame-Update neu zeichnen, sollte durch die gewünschte Framerate begrenzt sein - Sie können dies adaptiv machen, basierend auf einer Metrik, wie lange vorherige Draw-Operationen dauerten und wie tief die Dirty-Liste wird Balance zwischen Bildrate und sichtbarem Datenalter.
Dies ist besonders geeignet, wenn Sie versuchen, alle Daten auf dem Bildschirm auf einmal zu ziehen. Wenn Sie nur einen Teil der Daten anzeigen (wie in einer scrollbaren Ansicht) und eine gewisse Übereinstimmung zwischen den Array-Positionen und der Fenstergröße besteht, können Sie die Daten "windfen" - berücksichtigen Sie bei jedem Zeichenaufruf nur die Teilmenge der Daten, die sich tatsächlich auf dem Bildschirm befinden. Wenn Sie ein Zoom-Objekt haben, können Sie die beiden Methoden kombinieren - das kann kompliziert werden.
Wenn die Daten, wie gefenstert werden, dass der Wert in jedem Array-Elemente ist, was bestimmt, ob der Datenpunkt am oder außerhalb des Bildschirms ist, sollten eine sortierte Liste von Paaren verwendet, wo die Sortierschlüssel der Wert sind. Auf diese Weise können Sie die in dieser Situation beschriebene Fensteroptimierung durchführen. Wenn die Fensterung in beiden Dimensionen stattfindet, müssen Sie höchstwahrscheinlich nur die eine oder andere Optimierung durchführen, aber es gibt zweidimensionale Bereichsabfragestrukturen, die Ihnen dies ebenfalls geben können.
Lassen Sie uns sagen, dass meine Annahme um eine feste Datengröße falsch war; Stattdessen fügen Sie am Ende der Liste Daten hinzu, aber vorhandene Datenpunkte ändern sich nicht. In diesem Fall ist es wahrscheinlich besser, wenn Sie eine Queue-ähnliche Struktur verwenden, bei der alte Datenpunkte und nicht ein Array gelöscht werden, da ein wachsendes Array dazu führt, dass die Anwendung unnötigerweise stottert.
In diesem Fall besteht Ihre Optimierung darin, in einen Puffer vorzuzeichnen, der Ihrer Warteschlange folgt - wenn neue Elemente in die Warteschlange eintreten, verschieben Sie den ganzen Puffer nach links und zeichnen nur die Region mit den neuen Elementen.
Wenn es die/rate/der Dateneingabe ist, verwenden Sie eine Warteschlangenstruktur und überspringen Sie Elemente - entweder reduzieren Sie sie, wenn sie zur Warteschlange hinzugefügt werden, speichern/zeichnen jedes Element .
Wenn es stattdessen der Renderprozess ist, der all Ihre Zeit in Anspruch nimmt, ziehen Sie in Erwägung, auf einem Hintergrund-Thread zu rendern und das gerenderte Bild zu speichern. Auf diese Weise können Sie so viel Zeit aufwenden, wie Sie möchten - die Framerate innerhalb des Diagramms selbst wird jedoch nicht die allgemeine Reaktionsfähigkeit Ihrer Anwendung beeinträchtigen.
Wie möchten Sie die Handlung zeichnen, wenn es viele Punkte gibt? Wird es scrollbar sein? Oder die Handlung wird nach links verschoben und alte Punkte werden versteckt? In jedem Fall können Sie nur den sichtbaren Teil des Diagramms neu zeichnen, so dass es nicht viel Zeichnen gibt. – esentsov
Sind all diese Punkte gleichzeitig sichtbar? –
@esentov Ich möchte es automatisch scrollen, wenn neue Punkte erscheinen. Ich brauche nur neue Punkte, damit die alten zerstört werden können. – sebap123