Was das Beobachten der Zwischenablage kostet
macOS veröffentlicht keine Meldung, wenn sich die Zwischenablage ändert. Es gibt keinen Rückruf zum Anmelden, jede Zwischenablage-Verwaltung fragt also ab. Sie liest eine einzige ganze Zahl, NSPasteboard.general.changeCount, ein paarmal in der Sekunde und vergleicht sie mit dem zuletzt gesehenen Wert. Hat sich die Zahl nicht bewegt, passiert überhaupt nichts.
Das ist der ganze Beobachtungsmechanismus. Wenn dich eine Verwaltung echte Rechenzeit kostet, während du nicht kopierst, ist das Abfragen nicht der Grund.
Arbeit beginnt erst, wenn sich die Zahl ändert. Diese Arbeit ist: die Zwischenablage lesen, entscheiden, welcher Typ der Inhalt ist, und ihn irgendwohin schreiben. Sie passiert einmal je Kopie, und Kopien sind selten, auf der Skala, die einen Prozessor interessiert.
Wo die Kosten sich wirklich verstecken
Bilder. Ein Bildschirmfoto sind ein paar Megabyte. Leg diese Bytes in die Datenbank neben deine Textzeilen, und die Datei wächst schnell. Jede Abfrage zieht dann mehr Daten herum, und das Lesen wird langsamer, während der Verlauf sich füllt.
Das richtig hinzubekommen hat mich länger gekostet als jeder andere Teil der App. Ein eingefügtes Bild überhaupt einen Neustart überleben zu lassen war schwerer, als es aussieht. Die Antwort, die funktioniert, war: Bildbytes in eigene Dateien zu legen, nach ihrer Prüfsumme benannt, entdoppelt, und in der Datenbank nur einen Verweis zu halten.
Prüfsummen und Schreiben auf dem falschen Strang. Sobald Bilder in Dateien gehen, muss etwas mehrere Megabyte prüfsummen und auf die Platte schreiben. Mach das auf dem Hauptstrang, und du hast ein Stocken in den Akt des Kopierens eingebaut — genau den Moment, in dem der Nutzer hinsieht. Dieser Weg muss für alles Große vom Hauptstrang herunter, und das Lesen der Zwischenablage selbst muss auf dem Hauptstrang bleiben, weil es nicht strangsicher ist. Das sauber zu trennen ist fummelig.
Mein eigenes Verlaufsfenster liest eine Seite auf einmal aus der Datenbank, mit Suche und Filtern in die Abfrage hinuntergedrückt. Eine frühere Fassung lud zuerst einen Index von allem in den Arbeitsspeicher, was bei ein paar hundert Einträgen in Ordnung war und bei mehreren tausend schrecklich.
Zwei getrennte Zahlen zählen dafür. Wie viele Einträge das Fenster im Arbeitsspeicher hält, und wie viele die Datenbank auf der Platte hält. Sie zu verwechseln ist der Weg, auf dem eine Verwaltung deinen ganzen Verlauf im RAM hält, um eine Liste mit zehn Zeilen zu zeichnen.
Texterkennung. Text aus jedem kopierten Bild zu lesen kostet echte Rechenzeit, bei der Kopie, ob du je nach diesem Text suchen wirst oder nicht. Es auf Zuruf statt bei jeder Kopie zu tun ist der Unterschied zwischen einer Funktion und einer Steuer.
Formatierter Text. HTML unter macOS in gestalteten Text zu verwandeln läuft über einen alten WebKit-Importeur. Der erste Aufruf in einem Prozess lädt dieses ganze Gerüst, die erste formatierte Vorschau nach dem Start ist also merklich langsamer als jede danach. Die Abhilfe ist schmucklos: still nach dem Start aufwärmen, dann das Ergebnis je Eintrag zwischenspeichern.
Aufräumen auf dem heißen Weg. Mein eigener schlimmster Fall. Ein Wartungsdurchgang, der nach verwaisten Bilddateien suchte, wurde aus der Aufbewahrungsroutine gerufen, die bei jeder einzelnen Kopie lief. Er durchsuchte jeden gespeicherten Eintrag und jede Datei im Blob-Ordner, um Dateien zu finden, auf die nichts verweist. Bei vollem Verlauf fügte das jedem Kopieren eine sichtbare Verzögerung hinzu, jedes Mal. Er läuft jetzt beim Start und beim Leeren des Verlaufs, und nirgends in der Nähe einer Kopie.
Was Leute tatsächlich bemerken
Reaktionsfreude schlägt Ressourcenverbrauch darin, wie schnell sich ein Programm anfühlt. Das Fenster erscheint in dem Moment, in dem du das Kürzel drückst, oder es tut es nicht. Eine anderswo unsichtbar gesparte Millisekunde kauft das nicht zurück.
Der härteste Fehler, den ich hatte, gehört in diese Kategorie. Das Fenster wollte sich beim Loslassen der Tasten nicht schließen, und ich habe drei Stunden daran verbracht, bevor ich herausfand, dass ich gegen die Art ankämpfte, wie macOS Tastaturereignisse ausliefert. Nichts daran war ein Leistungsproblem im üblichen Sinn. Es ließ die App trotzdem kaputt wirken.