FunktionenPreiseDokumentationBlog
mote holen
← Blog
Entwicklung·21. August 2026·5 Min. Lesezeit

Wie wir dafür gesorgt haben, dass das Programm im Leerlauf keine CPU beansprucht

Der Editor ist den ganzen Tag geöffnet, aber tatsächlich tippt man nur während eines Teils dieser Zeit. In der übrigen Zeit plant mote weder Frames noch Timer ein und stellt dies zweifach sicher – durch Codeprüfungen und Messungen auf echter Hardware.

m
mote
Das Ergebnis eines Durchlaufs durch das Gate. Gemessen wurde in der Dev-Variante mit einem 100-KB-Dokument auf einer echten GPU: In den zehn Sekunden nach dem Öffnen des Fensters wurden 0 Frames gezeichnet, und die CPU-Auslastung im Leerlauf betrug 0,10 %.
Das Ergebnis eines Durchlaufs durch das Gate. Gemessen wurde in der Dev-Variante mit einem 100-KB-Dokument auf einer echten GPU: In den zehn Sekunden nach dem Öffnen des Fensters wurden 0 Frames gezeichnet, und die CPU-Auslastung im Leerlauf betrug 0,10 %.

Der Editor ist die Anwendung, die auf einem Laptop am längsten geöffnet bleibt. Aber die Zeit, in der tatsächlich geschrieben wird, ist nicht lang. Meistens bleibt er einfach still geöffnet, während man andere Dinge erledigt.

Deshalb hat mote einen Grundsatz aufgestellt.

Wenn sich das Dokument nicht ändert und keine Animation läuft, geschieht nichts.

Es gibt weder geplante Frames noch sich wiederholende Timer noch regelmäßige Überprüfungen. Das ist keine Optimierung, sondern ein Gestaltungsprinzip, das noch vor allen Funktionen eingehalten werden muss.

Wenn nichts geschieht, gibt es auch 0 Frames

Allein anhand der CPU-Auslastung lässt sich nur schwer erkennen, ob eine Anwendung stillsteht. Denn die Werte schwanken bei jeder Messung und werden durch Rundung leicht zu 0.

Deshalb betrachtet mote zuerst die Anzahl der Frames. Wenn sich ein Dokument in den zehn Sekunden nach dem Öffnen des Fensters nicht verändert, muss die Zahl der gezeichneten Frames exakt 0 betragen. Sie werden direkt in der Anwendung gezählt, und sobald auch nur ein einziger Frame gezeichnet wird, wird der Code nicht zusammengeführt.

Selbst bei 0 Frames können wir uns noch nicht zurücklehnen. Denn im Verborgenen können Threads weiterhin aufwachen. Deshalb zeichnen wir auch auf, wie oft sämtliche Threads des Prozesses pro Sekunde aufwachen. Da wir hierfür noch Referenzwerte sammeln, blockieren wir die Entwicklung noch nicht allein aufgrund dieses Werts.

Die einzige Ausnahme ist das Blinken des Carets. Dafür wird kein sich wiederholender Timer verwendet; nach jedem Blinken wird die nächste Aktion erneut eingeplant. Sobald das Fenster den Fokus verliert, hört es sofort auf. Das CPU-Budget im Leerlauf einschließlich des Carets beträgt 0,3 %.

Wir betrachten die Leerlaufleistung nicht isoliert. Wenn das Zeichnen hinausgezögert wird, lässt sich die Zahl der Frames leicht auf 0 bringen, aber dann erscheinen eingegebene Zeichen möglicherweise verspätet. Deshalb prüfen wir gleichzeitig die Eingabeverzögerung, die Startgeschwindigkeit und den Speicherverbrauch. Sobald auch nur einer der Grenzwerte überschritten wird, wird der Code nicht zusammengeführt.

Die harten Grenzwerte in der Budgettabelle — 0 Leerlauf-Frames / 10 s, 0,3 % CPU-Auslastung im Leerlauf, von außen gemessene Taste→Pixel-Latenz p95 von 33,4 ms, intern gemessene Tastenverarbeitung p95 von 4 ms, unser Anteil am Kaltstart von 10 ms und unser Anteil am Speicherverbrauch von 8 MB. In der untersten Zeile stehen die vier Messbedingungen
Die harten Grenzwerte in der Budgettabelle — 0 Leerlauf-Frames / 10 s, 0,3 % CPU-Auslastung im Leerlauf, von außen gemessene Taste→Pixel-Latenz p95 von 33,4 ms, intern gemessene Tastenverarbeitung p95 von 4 ms, unser Anteil am Kaltstart von 10 ms und unser Anteil am Speicherverbrauch von 8 MB. In der untersten Zeile stehen die vier Messbedingungen

Einmal im Code, einmal auf echter Hardware

Grundsätze verschwimmen mit der Zeit. Deshalb prüfen wir sie zweimal.

Zuerst prüfen wir den Code. Wir suchen automatisch nach sich wiederholenden Timern, niemals endenden Ticks, Polling, das immer wieder in den Ruhezustand wechselt und aufwacht, sowie nach Code, der unnötigerweise die gesamte Datei erneut einliest. Wird so etwas gefunden, stoppt die CI an dieser Stelle. Ist eine Ausnahme unbedingt erforderlich, muss direkt über dem Code erklärt werden, warum die Aufgabe endet.

Danach messen wir auf echter Hardware. Dabei halten wir vier Bedingungen ein.

Wir messen auf einem echten Bildschirm mit GPU. Der Mauszeiger befindet sich außerhalb des Fensters. Wir verwenden einen echten Sitzungsbus, und die Frames werden genau in dem Moment gezählt, in dem sie gezeichnet werden.

Diese Bedingungen sind aus Fehlschlägen entstanden. Einmal entstanden allein deshalb 150 Leerlauf-Frames, weil sich der Mauszeiger über dem Fenster befand. In einer isolierten Sitzung verzögerte sich der Start um mehrere Sekunden, weil das Toolkit auf eine Antwort wartete. Als wir einen Frame-Zähler verwendeten, der seine Werte verspätet meldete, wurden sogar Frames des Startbildschirms dem Leerlaufzeitraum zugerechnet.

Auch den Speicher beurteilen wir nicht anhand eines absoluten Werts. Denn der vom Toolkit und vom Grafiktreiber belegte Speicher kann je nach Umgebung um mehrere Dutzend MB variieren.

Stattdessen verwenden wir ein leeres Dokument als Referenz. Wir betrachten nur, wie viel mehr Speicher beim Öffnen eines Dokuments im Vergleich zu einem leeren Dokument verbraucht wird. Bei einer aktuellen Messung belegte das leere Dokument 116 MB und das 100-KB-Dokument 120 MB. Der zusätzliche Speicherverbrauch von mote betrug 4 MB und lag damit innerhalb des Budgets von 8 MB.

Wir haben nicht von Anfang an so gemessen. Einmal glaubten wir, das Speicherbudget überschritten zu haben, doch tatsächlich war nicht der Speicherverbrauch der Anwendung gestiegen, sondern der Grundverbrauch der Ausführungsumgebung. Seit diesem Tag messen wir anstelle des absoluten Werts nur noch den Anteil, den unsere Funktionen zusätzlich verbrauchen.

Das vom Gate verwendete 100-KB-Testdokument im Live-Modus — die Statuszeile unten zählt 20.584 Wörter und 96.513 Zeichen. Der Unterschied zwischen diesem Dokument und einem leeren Dokument ist der im Budget genannte „unser Anteil“
Das vom Gate verwendete 100-KB-Testdokument im Live-Modus — die Statuszeile unten zählt 20.584 Wörter und 96.513 Zeichen. Der Unterschied zwischen diesem Dokument und einem leeren Dokument ist der im Budget genannte „unser Anteil“

Während der Entwicklung zeigen wir auch die Anzahl der aktiven Timer auf dem Bildschirm an. Ist sie nicht 0, erkennen wir das sofort, noch bevor wir einen Commit erstellen.

Auch das automatische Speichern folgt diesem Grundsatz. Nur wenn sich das Dokument geändert hat, wird einmalig ein Timer gesetzt, der nach dem Speichern wieder entfernt wird. Die Anwendung wacht nicht regelmäßig auf, um zu prüfen: „Hat sich etwas geändert?“

Diese Zahlen sind nicht dazu da, die Konkurrenz zu schlagen

Anfangs wollten wir die Leerlaufleistung als einen Vorteil gegenüber Typora präsentieren. Doch als wir selbst nachmaßen, war das nicht der Fall.

Auf demselben Gerät und unter denselben Bedingungen betrug die CPU-Auslastung von Typora im Leerlauf 0,1 %. Sie war damit praktisch identisch mit der von mote. Einen bestätigten Unterschied gab es bei Obsidian mit 0,8 % und MarkText mit 0,6 %.

Wir haben es auch schon einmal falsch dargestellt. Eine Zeit lang stand in der Dokumentation: „Typora verbraucht CPU, wenn man es geöffnet lässt.“ Die als Beleg verwendeten 34,6 % waren jedoch nicht der Messwert von Typora, sondern der von apostrophe. Nachdem wir das erneut überprüft hatten, korrigierten wir den Satz sofort.

0 Leerlauf-Frames sind keine Behauptung gegenüber der Konkurrenz. Sie sind eine Disziplin, die mote sich selbst auferlegt. Denn wenn keine sich wiederholenden Aufgaben laufen, können wir jederzeit erklären, was die Anwendung gerade tut.

Wegen dieses Grundsatzes haben wir auch auf einiges verzichtet

Oft können wir nicht den bequemen Weg wählen.

Anstatt regelmäßig zu prüfen, ob eine Datei von außen verändert wurde, müssen wir Änderungsbenachrichtigungen des Betriebssystems empfangen. Anstatt Formeln einer Webview zu überlassen, haben wir eine eigene Layout-Engine entwickelt. Auch Animationen dürfen nicht dauerhaft weiterlaufen. Jede Bewegung hat einen Anfang und ein Ende, und nach ihrem Ende muss sie vollständig zum Stillstand kommen.

Wir werden nicht behaupten, dass der Akku dadurch einige Stunden länger hält. Denn das ist eine Zahl, die wir nicht gemessen haben. Was wir überprüft haben, sind die Anzahl der Frames, die CPU-Auslastung und sogar die Häufigkeit, mit der Threads aufwachen.

Nichts tun, wenn nichts geschieht.

Bei mote ist das keine Funktion, sondern ein Grundsatz, den jede Funktion erfüllen muss.

← ÄlterWarum wir uns für ein Preismodell entschieden haben, bei dem ein Kauf für alle 1.x-Versionen giltNeuer →Warum wir Zahlen veröffentlichen, statt nur zu sagen, dass es leichtgewichtig ist
Bleiben Sie per RSS auf dem Laufenden.
Nur das Schreiben bleibt.
Deutsch
© 2026 mote