Windows Dev Center

Verbessern der Leistung in Hilo (Windows Store-Apps mit C++ und XAML)

Aus: Umfassende Entwicklung einer Windows Store-App mit C++ und XAML: Hilo

Leitfaden-Logo

Vorherige Seite | Nächste Seite

Das Hilo-C++-Team hat einige Zeit investiert, um herauszufinden, was beim Erstellen einer dynamischen App sinnvoll und wovon abzuraten ist. Dabei wurden Bereiche in der App identifiziert, in denen die wahrgenommene Leistung verbessert werden musste, und Bereiche, in denen die tatsächliche Leistung verbessert werden musste. Hier sind einige Tipps und Codierungsrichtlinien für das Erstellen einer leistungsfähigen App mit hoher Reaktionsfähigkeit.

Download

Herunterladen des Hilo-Beispiels
Buch herunterladen (PDF)

Anweisungen zu dem heruntergeladenen Code finden Sie unter Erste Schritte mit Hilo.

Sie erfahren Folgendes:

  • Die Unterschiede zwischen Leistung und wahrgenommener Leistung.
  • Empfohlene Strategien für die Erstellung eines App-Profils.
  • Tipps zum Erstellen einer dynamischen App.
  • Wie Sie dafür sorgen, dass die App-UI reaktionsfähig bleibt, indem Sie rechenintensive Vorgänge in einem Hintergrundthread ausführen.

Betrifft

  • Windows-Runtime für Windows 8
  • Visual C++-Komponentenerweiterungen (C++/CX)
  • XAML

Erhöhen der Leistung mit App-Profilerstellung

Benutzer habe eine Reihe von Erwartungen an Apps. Sie möchten, dass die App sofort auf Fingereingaben, Mausklicks, Gesten und das Drücken von Tasten reagiert. Sie erwarten, dass Animationen glatt und fließend sind und nicht angehalten werden, weil die App nicht Schritt hält.

Leistungsprobleme können in unterschiedlicher Form auftreten. Sie können die Akkulaufzeit verringern, dazu führen, dass das Verschieben und Bildläufe langsamer als die Bewegung des Fingers erfolgen, oder sogar verursachen, dass die App für einen gewissen Zeitraum nicht reagiert. Ein Verfahren, mit dem sich bestimmen lässt, wo Codeoptimierungen die größte Wirkung beim Reduzieren von Leistungsproblemen haben, ist die App- Profilerstellung.

Mit den Profilerstellungstools für Windows Store-Apps können Sie Leistungsprobleme im Code bestimmen und Schritte zu ihrer Lösung unternehmen. Der Profiler sammelt Zeitinformationen für Apps. Dies erfolgt mit einem Sampling-Verfahren, bei dem CPU-Aufruflisteninformationen in regelmäßigen Intervallen erfasst werden. Bei der Profilerstellung werden Informationen über die Leistung der App angezeigt, und Sie können in den Ausführungspfaden des Codes sowie den Ausführungskosten der Funktionen navigieren, damit Sie die besten Optimierungs- möglichkeiten bestimmen können. Weitere Informationen finden Sie unter So erstellen Sie ein Profil von Visual C++-, Visual C#- und Visual Basic-Code in Windows Store-Apps auf einem lokalen Computer. Informationen zum Analysieren der vom Profiler zurückgegebenen Daten finden Sie unter Analysieren von Leistungsdaten für Visual C++-, Visual C#- und Visual Basic- Code in Windows Store-Apps.

Beim Optimieren der Leistung geht es nicht nur um das Implementieren von effizienten Algorithmen. Zur Leistung zählt auch die vom Benutzer wahrgenommene App-Leistung während der Verwendung der App. Die App-Erfahrung des Benutzers lässt sich in drei Kategorien unterteilen: Wahrnehmung, Toleranz und Reaktionsfähigkeit.

  • Wahrnehmung. Die Wahrnehmung der Leistung durch einen Benutzer lässt sich als die erinnerte Dauer definieren, die zum Ausführen der Aufgaben des Benutzers in der App benötigt wurde. Wahrgenommene und reale Leistung stimmen nicht immer überein. Die wahrgenommene Leistung lässt sich verbessern, indem die Zeitspanne zwischen Aktivitäten, die der Benutzer zum Abschließen einer Aufgabe in einer App ausführen muss, verringert wird.
  • Toleranz. Das Ausmaß der vom Benutzer tolerierten Verzögerung hängt von der vom Benutzer erwarteten Dauer eines Vorgangs ab. Beispielsweise kann ein Benutzer die Funktion zum Zuschneiden eines Bilds inakzeptabel finden, wenn die App während des Zuschneidens nicht mehr reagiert, und sei dies nur für einige Sekunden. Die Toleranz eines Benutzers für Verzögerungen lässt sich erhöhen, indem Sie Bereiche der App identifizieren, die sehr viel Verarbeitungszeit erfordern, und die Unsicherheit des Benutzers während dieser Szenarien beschränken oder beseitigen, indem Sie eine visuelle Fortschrittsanzeige bereitstellen. Darüber hinaus können asynchrone APIs verwendet werden, um zu verhindern, dass der UI-Thread blockiert wird und die App daher eingefroren zu sein scheint.
  • Reaktionsfähigkeit. Die Reaktionsfähigkeit einer App wird relativ zur ausgeführten Aktivität bestimmt. Um die Leistung einer Aktivität zu messen und zu bewerten, ist ein Zeitintervall erforderlich, das als Vergleichsmaßstab dient. Das Hilo-Team setzte voraus, dass die App Feedback in Form einer Statusanzeige für den Benutzer bereitstellen muss, wenn eine Aktivität länger als 500 ms dauert.

Tipps für die Profilerstellung

Beachten Sie bei der Profilerstellung für die App die folgenden Tipps, um sicherzustellen, dass zuverlässige und reproduzierbare Leistungsmessungen durchgeführt werden:

  • Windows 8 wird auf einer großen Vielfalt unterschiedlicher Geräte ausgeführt, und Leistungsmessungen für ein Hardwareelement zeigen nicht immer die Leistungsmerkmale von anderen Formfaktoren.
  • Stellen Sie sicher, dass die Stromversorgung des Geräts, auf dem Leistungsmessungen erfolgen, über das Stromnetz und nicht über einen Akku erfolgt. Viele Systeme sparen Energie, wenn die Stromversorgung über einen Akku erfolgt, und werden daher anders ausgeführt.
  • Stellen Sie sicher, dass die Gesamtauslastung des Arbeitsspeichers auf dem System unter 50 % beträgt. Wenn sie höher ist, schließen Sie Apps, bis Sie 50 % erreichen, um sicherzustellen, dass Sie die Auswirkungen der App und nicht die Auswirkungen von anderen Prozessen messen.
  • Wenn Sie die Profilerstellung der App remote ausführen, wird empfohlen, direkt auf dem Remotegerät mit der App zu interagieren. Wenn Sie mit der App über eine Remotedesktopverbindung interagieren, kann dies zu erheblichen Änderungen der Leistung der App und der von Ihnen erfassten Leistungsdaten führen. Weitere Informationen finden Sie unter So erstellen Sie ein Profil von Visual C++-, Visual C#- und Visual Basic-Code in Windows Store-Apps auf einem Remotegerät.
  • Um möglichst genaue Leistungsergebnisse zu erhalten, erstellen Sie das Profil eines Releasebuilds der App. Weitere Informationen finden Sie unter Gewusst wie: Festlegen von Debug- und Releasekonfigurationen.
  • Erstellen Sie das Profil der App nicht im Simulator, da der Simulator die Leistung der App verzerren kann.

Weitere Leistungstools

Zusätzlich zu den Profilerstellungstools zum Messen der App- Leistung verwendete das Hilo-Team die Windows- Zuverlässigkeits- und Leistungsüberwachung (perfmon). Mit perfmon können Sie überprüfen, wie sich ausgeführte Programme auf die Leistung des Computers auswirken, und zwar sowohl in Echtzeit als auch durch das Erfassen von Protokolldaten für die spätere Analyse. Mit diesem Tool generierte das Hilo-Team eine allgemeine Diagnose der Leistung der App. Weitere Informationen über perfmon finden Sie unter Windows- Zuverlässigkeits- und Leistungsüberwachung.

[Oben]

Tipps für die Leistung

Das Hilo-Team hat einige Zeit aufgewendet, um herauszufinden, was beim Erstellen einer dynamischen App sinnvoll ist und wovon abzuraten ist. Die folgenden Punkten sollte beachtet werden.

Sorgen Sie dafür, dass die Startzeit der App kurz bleibt

Laden Sie große speicherinterne Objekte nicht, während die App aktiviert wird. Wenn umfangreiche Aufgaben ausgeführt werden müssen, stellen Sie einen benutzerdefinierten Begrüßungsbildschirm bereit, damit die App diese Aufgaben im Hintergrund ausführen kann.

Fördern Sie die Reaktionsfähigkeit Ihrer Apps, indem Sie asynchrone API-Aufrufe im UI-Thread verwenden

Blockieren Sie nicht den UI-Thread mit synchronen APIs. Verwenden Sie stattdessen asynchrone APIs, oder rufen Sie APIs in einem nicht blockierenden Kontext auf. Zudem sollten Vorgänge mit intensiver Verarbeitung in einen Threadpoolthread verschoben werden. Dies ist wichtig, da Verzögerungen, die länger als 100 ms sind, mit hoher Wahrscheinlichkeit von Benutzern wahrgenommen werden. Rechenintensive Vorgänge sollten in eine Reihe kleinerer Vorgänge unterteilt werden, damit der UI-Thread zwischen den Vorgängen auf Benutzereingaben lauscht.

Verwenden von Miniaturbildern für das schnelle Rendern

Die Dateisystem- und Mediendateien sind ein wichtiger Bestandteil der meisten Apps und zudem eine der häufigsten Ursachen für Leistungsprobleme. Der Dateizugriff bildet üblicherweise einen wichtigen Leistungsengpass für Apps, die Galerieansichten von Dateien, z. B. Fotodateien, anzeigen. Der Zugriff auf Bilder kann langsam erfolgen, da Arbeitsspeicher und CPU-Zyklen zum Speichern sowie zum Decodieren und Anzeigen des Bilds benötigt werden.

Anstatt ein Bild voller Größe für die Anzeige als Miniaturansicht herunterzuskalieren, sollten Sie die Miniaturansicht-APIs der Windows-Runtime verwenden. Die Windows-Runtime stellt eine Reihe von APIs bereit, die von einem effizienten Cache unterstützt werden. Dieser ermöglicht das schnelle Abrufen einer kleineren Version eines Bilds, das als Miniaturansicht genutzt werden kann.

Rufen Sie Miniaturansichten im Voraus ab.

Die Windows-Runtime stellt nicht nur APIs zum Abrufen von Miniaturansichten bereit, sondern enthält in ihrer API auch die SetThumbnailPrefetch-Methode. Diese Methode gibt entsprechend dem Zweck der Miniaturansicht, der angeforderten Größe und dem gewünschten Verhalten zum Abrufen des Miniaturbilds die für jede Datei bzw. jeden Ordner abzurufende Miniaturansicht an.

Die FileSystemRepository-Klasse in Hilo fragt das Dateisystem nach Fotos ab, die bestimmte Kriterien erfüllen, und gibt diese Fotos zurück. Die CreateFileQuery-Methode gibt mithilfe der SetThumbnailPrefetch-Methode Miniaturansichten im Abfrageresultset zurück.

FileSystemRepository.cpp


inline StorageFileQueryResult^ FileSystemRepository::CreateFileQuery(IStorageFolderQueryOperations^ folder, String^ query, IndexerOption indexerOption)
{
    auto fileTypeFilter = ref new Vector<String^>(items);
    auto queryOptions = ref new QueryOptions(CommonFileQuery::OrderByDate, fileTypeFilter);
    queryOptions->FolderDepth = FolderDepth::Deep;
    queryOptions->IndexerOption = indexerOption;
    queryOptions->ApplicationSearchFilter = query;
    queryOptions->SetThumbnailPrefetch(ThumbnailMode::PicturesView, 190, ThumbnailOptions::UseCurrentScale);
    queryOptions->Language = CalendarExtensions::ResolvedLanguage();
    return folder->CreateFileQueryWithOptions(queryOptions);
}


In diesem Fall ruft der Code Miniaturansichten im Voraus ab, mit denen für jedes Foto eine Vorschau mit einer Breite von bis zu 190 Pixeln angezeigt wird,und erhöht die angeforderte Größe der Miniaturansicht auf Grundlage der PPI (Pixel Per Inch, Pixel pro Zoll)der Anzeige. Mit der SetThumbnailPrefetch-Methode lässt sich die Zeit zum Anzeigen einer Ansicht von Fotos aus den Bildern des Benutzers um 70 % verringern.

Kürzen Sie Ressourcenwörterbücher

Ressourcen für die gesamte App sollten im Application-Objekt gespeichert werden, um Duplizierung zu vermeiden. Spezifische Ressourcen für einzelne Seiten sollten jedoch in das Ressourcenwörterbuch der Seite verschoben werden.

Optimieren Sie die Elementanzahl

Das XAML-Framework dient zum Anzeigen Tausender von Objekten, jedoch erhöhen Sie die Geschwindigkeit der App, wenn Sie die Anzahl von Elementen auf einer Seite verringern. Sie können die Elementanzahl einer Seite verringern, indem Sie unnötige Elemente vermeiden und Elemente reduzieren, die nicht sichtbar sind.

Verwenden Sie unabhängige Animationen

Eine unabhängige Animation wird unabhängig vom UI-Thread ausgeführt. Viele der in XAML verwendeten Animationstypen bestehen aus einem Kompositionsmodul, das in einem eigenen Thread ausgeführt wird, wobei die Aufgaben des Moduls von der CPU auf den Grafikprozessor ausgelagert werden. Das Verschieben der Animationskomposition in einen Nicht-UI-Thread verhindert, dass die Animation flimmert oder von der im UI-Thread ausgeführten App blockiert wird. Das Erstellen der Animation im Grafikprozessor erhöht die Leistung immens, sodass Animationen flüssig und mit gleichmäßiger Framerate ausgeführt werden.

Zum Erstellen von unabhängigen Animationen benötigen Sie kein zusätzliches Markup. Das System bestimmt, wann die Animation unabhängig erstellt werden kann, jedoch gelten für unabhängige Animationen einige Beschränkungen. Hier sind einige häufige Probleme.

  • Das Animieren der Height-Eigenschaft und der Width-Eigenschaft eines UIElement führt zu einer abhängigen Animation, da diese Eigenschaften Layoutänderungen erfordern, die nur im UI-Thread ausgeführt werden können. Um einen ähnlichen Effekt wie das Animieren von Height oder Width zu erzielen, können Sie den Maßstab des Steuerelements animieren.
  • Wenn Sie die CacheMode-Eigenschaft eines Elements auf BitmapCache festlegen, werden alle Animationen in der visuellen Unterstruktur unabhängig ausgeführt. Sie können dies vermeiden, indem Sie einfach keinen zwischengespeicherten Inhalt animieren.
  • Das ProgressRing-Steuerelement und das ProgressBar-Steuerelement verfügen über Endlosanimationen, die weiterhin ausgeführt werden können, auch wenn das Steuerelement nicht auf der Seite angezeigt wird. Dies kann verhindern, dass die CPU in den Energiespar- oder Leerlaufmodus wechselt. Legen Sie die ProgressRing::IsActive-Eigenschaft und dieProgressBar::IsIndeterminate-Eigenschaft auf "false" fest, wenn diese Steuerelemente nicht auf der Seite angezeigt werden.

In Hilo wird der ObjectAnimationUsingKeyFrames-Typ verwendet, der eine unabhängige Animation ist.

Verwenden Sie parallele Muster für rechenintensive Vorgänge

Wenn die App rechenintensive Vorgänge ausführt, müssen Sie mit hoher Wahrscheinlichkeit parallele Programmiertechniken verwenden. Es gibt eine Reihe von bewährten Mustern für die effiziente Nutzung von Hardware mit Mehrkernprozessor. Parallele Programmierung mit Microsoft Visual C++ ist eine Ressource für einige der häufigsten Muster, mit Beispielen, in denen PPL und die Asynchronous Agents Library verwendet werden. Eine umfassende Dokumentation der APIs mit Beispielen finden Sie unter Konkurrenz-Runtime.

Hilo enthält einige rechenintensive Vorgänge zum Bearbeiten von Bildern. Für diese Vorgänge verwendeten wir parallele Programmiertechniken, die die Hardware des Computers für parallele Verarbeitung nutzen. Weitere Informationen finden Sie unter Anpassen an die asynchrone Programmierung, Verwenden von paralleler Programmierung und Hintergrundaufgaben und Muster zum asynchronen Programmieren in C++ in diesem Handbuch.

Achten Sie auf den Aufwand für die Typkonvertierung

Für die Interaktion mit Windows-Runtime-Features müssen Sie zuweilen Datentypen aus dem Platform-Namespace und dem Windows-Namespace erstellen. In manchen Fällen führt das Erstellen von Objekten dieser Typen zu Aufwand für die Typkonvertierung. Um diesen Aufwand zu minimieren, führt Hilo Typkonvertierung in der abstrakten Binärschnittstelle aus. Weitere Informationen finden Sie unter Schreiben von modernem C++-Code in diesem Handbuch.

Verwenden Sie Verfahren, die Marshallingkosten verringern

Wenn der Code mit anderen Sprachen als C++ and XAML kommuniziert, können Kosten zum Marshallen von Daten für unterschiedliche Laufzeitumgebungen entstehen. Hilo interagiert nur mit C++ und XAML, daher waren die Marshallingkosten für uns ohne Belang. Weitere Informationen finden Sie unter Schreiben von modernem C++-Code in diesem Handbuch.

Sorgen Sie dafür, dass die Speicherauslastung der angehaltenen App gering ist

Wenn die App nach dem Anhalten fortgesetzt wird, wird sie fast unverzüglich wieder angezeigt. Wenn die App jedoch nach dem Beenden neu gestartet wird, kann es etwas länger dauern, bis sie wieder angezeigt wird. Daher lassen sich die Wahrnehmung der Reaktionsfähigkeit der App durch den Benutzer und seine entsprechende Toleranz optimieren, indem Sie verhindern, dass die App beim Anhalten beendet wird. Sie können dies erreichen, indem Sie die Speicherauslastung der angehaltenen App gering halten.

Wenn das Anhalten der App beginnt, sollte sie alle großen Objekte freigeben, die beim Fortsetzen ohne Aufwand neu erstellt werden können. So lässt sich der Speicherbedarf der App gering halten, und die Wahrscheinlichkeit dafür wird verringert, dass das Betriebssystem die App nach dem Anhalten beendet. Weitere Informationen finden Sie unter Behandeln von Anhalten, Fortsetzen und Aktivierung.

Minimieren Sie den Umfang der von der App verwendeten Ressourcen, indem Sie verarbeitungsintensive Vorgänge in kleinere Vorgänge unterteilen

Windows muss die Ressourcenanforderungen sämtlicher Windows Store-Apps erfüllen, indem angehaltene Apps beendet werden, damit andere Apps ausgeführt werden können. Dies führt dazu, dass andere Apps möglicherweise beendet werden, wenn Ihre App eine große Menge an Speicher nutzt, selbst wenn die App den Speicher kurz nach dem Anfordern freigibt. Verhalten Sie sich verantwortungsvoll, um zu verhindern, dass Benutzer wahrgenommene Latenz im System nicht auf Ihre App zurückführen. Zu diesem Zweck können Sie speicherintensive Vorgänge in eine Reihe kleinerer Vorgänge unterteilen.

[Oben]

 

 

Anzeigen:
© 2015 Microsoft