Messung der Ausführungszeit einer Funktion in C ++


137

Ich möchte herausfinden, wie viel Zeit eine bestimmte Funktion in meinem C ++ - Programm benötigt, um unter Linux ausgeführt zu werden . Danach möchte ich einen Geschwindigkeitsvergleich machen. Ich habe mehrere Zeitfunktionen gesehen, aber am Ende hatte ich diese durch Boost. Chrono:

process_user_cpu_clock, captures user-CPU time spent by the current process

Jetzt ist mir nicht klar, ob ich die obige Funktion verwende. Bekomme ich die einzige Zeit, die die CPU für diese Funktion aufgewendet hat?

Zweitens konnte ich kein Beispiel für die Verwendung der obigen Funktion finden. Kann mir bitte jemand helfen, wie man die obige Funktion benutzt?

PS: Im Moment verwende ich std::chrono::system_clock::now(), um Zeit in Sekunden zu erhalten, aber dies führt zu unterschiedlichen Ergebnissen aufgrund der unterschiedlichen CPU-Auslastung jedes Mal.


2
Für Linux verwenden: clock_gettime.. gcc definiert andere Uhren als: typedef system_clock steady_clock; typedef system_clock high_resolution_clock;unter Windows verwenden QueryPerformanceCounter.
Brandon

Ist diese Frage nicht ein Duplikat dieser einen oder haben die Szenarien machen die Lösungen anders?
Nordländer

Ich habe zwei Implementierungen einer Funktion und möchte herausfinden, welche besser funktioniert.
Nordländer

Sehr wichtig: Stellen Sie sicher, dass Sie die Optimierung aktivieren . Nicht optimierter Code weist andere Engpässe auf als normaler optimierter Code und sagt Ihnen nichts Sinnvolles. Hilfe zur C-Schleifenoptimierung für die endgültige Zuweisung (bei deaktivierter Compileroptimierung) . Und im Allgemeinen hat das Mikrobenchmarking viele Fallstricke, insbesondere das Versagen, zuerst eine Aufwärmschleife für CPU-Frequenz- und Seitenfehler durchzuführen: Idiomatische Methode zur Leistungsbewertung? . Und diese Antwort
Peter Cordes

Siehe auch Wie würden Sie die Leistung einer Funktion bewerten? für Google Benchmark, wodurch viele der Fallstricke beim Rollen Ihres eigenen Mikrobenchmarks vermieden werden. Auch das Benchmarking von Simple for () -Schleifen dauert mit jeder Schleife, die gebunden ist, um mehr darüber zu erfahren, wie die Optimierung mit Benchmark-Schleifen interagiert und was dagegen zu tun ist.
Peter Cordes

Antworten:


263

Es ist eine sehr einfach zu verwendende Methode in C ++ 11. Sie müssen std::chrono::high_resolution_clockaus dem <chrono>Header verwenden.

Verwenden Sie es so:

#include <iostream>
#include <chrono>

void function()
{
    long long number = 0;

    for( long long i = 0; i != 2000000; ++i )
    {
       number += 5;
    }
}

int main()
{
    auto t1 = std::chrono::high_resolution_clock::now();
    function();
    auto t2 = std::chrono::high_resolution_clock::now();

    auto duration = std::chrono::duration_cast<std::chrono::microseconds>( t2 - t1 ).count();

    std::cout << duration;
    return 0;
}

Dadurch wird die Dauer der Funktion gemessen.

HINWEIS: Sie erhalten nicht immer das gleiche Timing für eine Funktion. Dies liegt daran, dass die CPU Ihres Computers weniger oder mehr von anderen auf Ihrem Computer ausgeführten Prozessen verwendet werden kann, genauso wie Ihr Geist mehr oder weniger konzentriert sein kann, wenn Sie eine mathematische Übung lösen. Im menschlichen Geist können wir uns an die Lösung eines mathematischen Problems erinnern, aber für einen Computer wird der gleiche Prozess immer etwas Neues sein; So erhalten Sie, wie gesagt, nicht immer das gleiche Ergebnis!


Wenn ich diese Funktion verwende, habe ich beim ersten Durchlauf 118440535 Mikrosekunden und beim zweiten Durchlauf der gleichen Funktion 83221031 Mikrosekunden erhalten. Sollten die beiden Zeitmessungen nicht gleich sein, wenn ich nur die Dauer dieser Funktion messe?
Xara

1
Nein. Der Prozessor Ihres Computers kann weniger oder mehr verwendet werden. Das high_resolution_clockgibt Ihnen die physische und Echtzeit, die Ihre Funktion benötigt, um ausgeführt zu werden. In Ihrem ersten Lauf wurde Ihre CPU also weniger verbraucht als im nächsten Lauf. Mit "verwendet" meine ich, welche andere Anwendungsarbeit die CPU verwendet.
Victor

1
Ja, wenn Sie den Durchschnitt der Zeit benötigen, ist dies ein guter Weg, um ihn zu erhalten. Nehmen Sie drei Läufe und berechnen Sie den Durchschnitt.
Victor

3
Könnten Sie bitte die Postleitzahl ohne "Namespace verwenden" im Allgemeinen posten. Es macht es einfacher zu sehen, was von wo kommt.
Schneemann

1
Sollte das nicht ein sein steady_clock? Ist es nicht möglich, dass es high_resolution_clocksich um eine nicht monotone Uhr handelt?
Gillespie

15

Hier ist eine Funktion, die die Ausführungszeit jeder als Argument übergebenen Funktion misst:

#include <chrono>
#include <utility>

typedef std::chrono::high_resolution_clock::time_point TimeVar;

#define duration(a) std::chrono::duration_cast<std::chrono::nanoseconds>(a).count()
#define timeNow() std::chrono::high_resolution_clock::now()

template<typename F, typename... Args>
double funcTime(F func, Args&&... args){
    TimeVar t1=timeNow();
    func(std::forward<Args>(args)...);
    return duration(timeNow()-t1);
}

Anwendungsbeispiel:

#include <iostream>
#include <algorithm>

typedef std::string String;

//first test function doing something
int countCharInString(String s, char delim){
    int count=0;
    String::size_type pos = s.find_first_of(delim);
    while ((pos = s.find_first_of(delim, pos)) != String::npos){
        count++;pos++;
    }
    return count;
}

//second test function doing the same thing in different way
int countWithAlgorithm(String s, char delim){
    return std::count(s.begin(),s.end(),delim);
}


int main(){
    std::cout<<"norm: "<<funcTime(countCharInString,"precision=10",'=')<<"\n";
    std::cout<<"algo: "<<funcTime(countWithAlgorithm,"precision=10",'=');
    return 0;
}

Ausgabe:

norm: 15555
algo: 2976

2
@ RestlessC0bra: Die Implementierung ist definiert, high_resolution_clockkann ein Alias ​​von system_clock(Wanduhr) steady_clockoder eine dritte unabhängige Uhr sein. Details finden Sie hier . Für CPU-Uhr std::clockkann verwendet werden
Jahid

2
Zwei Makros und ein globales Typedef - von denen keines einen einzigen Tastendruck sicherstellt - sind sicherlich nichts, was ich als elegant bezeichnen würde. Auch das Übergeben eines Funktionsobjekts und das perfekte Weiterleiten der Argumente separat ist ein wenig übertrieben (und im Fall von überladenen Funktionen sogar unpraktisch), wenn Sie nur verlangen können, dass der Zeitcode in ein Lambda eingegeben wird. Aber gut, solange das Übergeben von Argumenten optional ist.
MikeMB

2
Und dies ist eine Rechtfertigung für die Verletzung jeder einzelnen Richtlinie zur Benennung von Makros? Sie stellen ihnen keine Präfixe vor, Sie verwenden keine Großbuchstaben, Sie wählen einen sehr gebräuchlichen Namen, der mit hoher Wahrscheinlichkeit mit einem lokalen Symbol kollidiert, und vor allem: Warum verwenden Sie überhaupt ein Makro (anstelle einer Funktion)? )? Und während wir gerade dabei sind: Warum geben Sie die Dauer überhaupt als doppeltes Nanosekunden zurück? Wir sollten uns wahrscheinlich einig sein, dass wir nicht einverstanden sind. Meine ursprüngliche Meinung lautet: "Dies ist nicht das, was ich eleganten Code nennen würde".
MikeMB

1
Das Problem ist, dass sie nicht kopiert sind. Ich mache mir Sorgen, dass solche Makros in einer Header-Datei landen, die (möglicherweise indirekt als Teil einer Bibliothek) in meinen Code aufgenommen wird. Wenn Sie einen Vorgeschmack darauf haben möchten, was passiert, wenn Für Makros werden gebräuchliche Namen verwendet, die windows.hin einem nicht trivialen c ++ - Projekt enthalten sind. In Bezug auf assertzunächst: "quod licet iovi non licet Bovi";). Zweitens werden nicht alle Entscheidungen in der Standardbibliothek (manchmal aus Jahrzehnten) nach modernen Maßstäben als gute Idee angesehen. Es gibt einen Grund, warum der Designer von C ++ - Modulen sehr bemüht ist, Makros nicht standardmäßig zu exportieren.
MikeMB

2
@ Jahid: Danke. In diesem Fall halte ich meine Kommentare für ungültig und null.
MikeMB

9

einfaches Programm, um eine benötigte Funktionsausführungszeit zu finden.

#include <iostream>
#include <ctime> // time_t
#include <cstdio>

void function()
{
     for(long int i=0;i<1000000000;i++)
     {
        // do nothing
     }
}

int main()
{

time_t begin,end; // time_t is a datatype to store time values.

time (&begin); // note time before execution
function();
time (&end); // note time after execution

double difference = difftime (end,begin);
printf ("time taken for function() %.2lf seconds.\n", difference );

return 0;
}

6
es ist sehr ungenau, zeigt nur Sekunden, aber keine Millisekunden
user25

6

In Scott Meyers Buch habe ich ein Beispiel für einen universellen generischen Lambda-Ausdruck gefunden, mit dem die Ausführungszeit von Funktionen gemessen werden kann. (C ++ 14)

auto timeFuncInvocation = 
    [](auto&& func, auto&&... params) {
        // get time before function invocation
        const auto& start = std::chrono::high_resolution_clock::now();
        // function invocation using perfect forwarding
        std::forward<decltype(func)>(func)(std::forward<decltype(params)>(params)...);
        // get time after function invocation
        const auto& stop = std::chrono::high_resolution_clock::now();
        return stop - start;
     };

Das Problem ist, dass Sie nur eine Ausführung messen, sodass die Ergebnisse sehr unterschiedlich sein können. Um ein zuverlässiges Ergebnis zu erhalten, sollten Sie eine große Anzahl von Ausführungen messen. Laut Andrei Alexandrescu Vortrag auf der Code :: Dive 2015 Konferenz - Schreiben von Fast Code I:

Gemessene Zeit: tm = t + tq + tn + bis

wo:

tm - gemessene (beobachtete) Zeit

t - der tatsächliche Zeitpunkt des Interesses

tq - Zeit, die durch Quantisierungsrauschen hinzugefügt wird

tn - Zeit, die durch verschiedene Geräuschquellen hinzugefügt wird

zu - Overhead-Zeit (Messen, Schleifen, Aufrufen von Funktionen)

Nach dem, was er später in der Vorlesung sagte, sollten Sie ein Minimum dieser großen Anzahl von Ausführungen als Ergebnis nehmen. Ich ermutige Sie, sich die Vorlesung anzusehen, in der er erklärt, warum.

Es gibt auch eine sehr gute Bibliothek von Google - https://github.com/google/benchmark . Diese Bibliothek ist sehr einfach zu bedienen und leistungsstark. Sie können einige Vorträge von Chandler Carruth auf Youtube lesen, wo er diese Bibliothek in der Praxis nutzt. Zum Beispiel CppCon 2017: Chandler Carruth „Going Nowhere Faster“;

Anwendungsbeispiel:

#include <iostream>
#include <chrono>
#include <vector>
auto timeFuncInvocation = 
    [](auto&& func, auto&&... params) {
        // get time before function invocation
        const auto& start = high_resolution_clock::now();
        // function invocation using perfect forwarding
        for(auto i = 0; i < 100000/*largeNumber*/; ++i) {
            std::forward<decltype(func)>(func)(std::forward<decltype(params)>(params)...);
        }
        // get time after function invocation
        const auto& stop = high_resolution_clock::now();
        return (stop - start)/100000/*largeNumber*/;
     };

void f(std::vector<int>& vec) {
    vec.push_back(1);
}

void f2(std::vector<int>& vec) {
    vec.emplace_back(1);
}
int main()
{
    std::vector<int> vec;
    std::vector<int> vec2;
    std::cout << timeFuncInvocation(f, vec).count() << std::endl;
    std::cout << timeFuncInvocation(f2, vec2).count() << std::endl;
    std::vector<int> vec3;
    vec3.reserve(100000);
    std::vector<int> vec4;
    vec4.reserve(100000);
    std::cout << timeFuncInvocation(f, vec3).count() << std::endl;
    std::cout << timeFuncInvocation(f2, vec4).count() << std::endl;
    return 0;
}

EDIT: Natürlich müssen Sie immer daran denken, dass Ihr Compiler etwas optimieren kann oder nicht. Werkzeuge wie perf können in solchen Fällen nützlich sein.


Interessant - was bringt es, hier ein Lambda gegenüber einer Funktionsvorlage zu verwenden?
user48956

1
Der Hauptunterschied wäre, dass es sich um ein aufrufbares Objekt handelt, aber mit variadic template und std :: result_of_t können Sie tatsächlich etwas sehr Ähnliches erhalten.
Krzysztof Sommerfeld

@KrzysztofSommerfeld Wie mache ich das für Funktionsmethoden? Wenn ich das Timing (Object.Method1) übergebe, wird der Fehler "Nicht-Standard-Syntax; benutze '&', um einen Zeiger auf Mitglied zu erstellen" zurückgegeben
RobinAtTech

timeFuncInvocation ([& objectName] (auto && ... args) {objectName.methodName (std :: forward <decltype (args)> (args) ...);}, arg1, arg2, ...); oder ommit & sign vor objectName (dann haben Sie eine Kopie des Objekts)
Krzysztof Sommerfeld

4

Einfacher Weg für älteres C ++ oder C:

#include <time.h> // includes clock_t and CLOCKS_PER_SEC

int main() {

    clock_t start, end;

    start = clock();
    // ...code to measure...
    end = clock();

    double duration_sec = double(end-start)/CLOCKS_PER_SEC;
    return 0;
}

Timing-Präzision in Sekunden ist 1.0/CLOCKS_PER_SEC


1
Dies ist nicht tragbar. Es misst die Prozessorzeit unter Linux und die Uhrzeit unter Windows.
BugSquasher

2
  • Es ist eine sehr einfach zu verwendende Methode in C ++ 11.
  • Wir können std :: chrono :: high_resolution_clock aus dem Header verwenden
  • Wir können eine Methode schreiben, um die Ausführungszeit der Methode in einer gut lesbaren Form zu drucken.

Zum Beispiel dauert es ungefähr 1 Minute und 40 Sekunden, um alle Primzahlen zwischen 1 und 100 Millionen zu finden. Die Ausführungszeit wird also wie folgt gedruckt:

Execution Time: 1 Minutes, 40 Seconds, 715 MicroSeconds, 715000 NanoSeconds

Der Code ist hier:

#include <iostream>
#include <chrono>

using namespace std;
using namespace std::chrono;

typedef high_resolution_clock Clock;
typedef Clock::time_point ClockTime;

void findPrime(long n, string file);
void printExecutionTime(ClockTime start_time, ClockTime end_time);

int main()
{
    long n = long(1E+8);  // N = 100 million

    ClockTime start_time = Clock::now();

    // Write all the prime numbers from 1 to N to the file "prime.txt"
    findPrime(n, "C:\\prime.txt"); 

    ClockTime end_time = Clock::now();

    printExecutionTime(start_time, end_time);
}

void printExecutionTime(ClockTime start_time, ClockTime end_time)
{
    auto execution_time_ns = duration_cast<nanoseconds>(end_time - start_time).count();
    auto execution_time_ms = duration_cast<microseconds>(end_time - start_time).count();
    auto execution_time_sec = duration_cast<seconds>(end_time - start_time).count();
    auto execution_time_min = duration_cast<minutes>(end_time - start_time).count();
    auto execution_time_hour = duration_cast<hours>(end_time - start_time).count();

    cout << "\nExecution Time: ";
    if(execution_time_hour > 0)
    cout << "" << execution_time_hour << " Hours, ";
    if(execution_time_min > 0)
    cout << "" << execution_time_min % 60 << " Minutes, ";
    if(execution_time_sec > 0)
    cout << "" << execution_time_sec % 60 << " Seconds, ";
    if(execution_time_ms > 0)
    cout << "" << execution_time_ms % long(1E+3) << " MicroSeconds, ";
    if(execution_time_ns > 0)
    cout << "" << execution_time_ns % long(1E+6) << " NanoSeconds, ";
}

0

Hier ist eine hervorragende Klassenvorlage nur für Header, um die verstrichene Zeit einer Funktion oder eines Codeblocks zu messen:

#ifndef EXECUTION_TIMER_H
#define EXECUTION_TIMER_H

template<class Resolution = std::chrono::milliseconds>
class ExecutionTimer {
public:
    using Clock = std::conditional_t<std::chrono::high_resolution_clock::is_steady,
                                     std::chrono::high_resolution_clock,
                                     std::chrono::steady_clock>;
private:
    const Clock::time_point mStart = Clock::now();

public:
    ExecutionTimer() = default;
    ~ExecutionTimer() {
        const auto end = Clock::now();
        std::ostringstream strStream;
        strStream << "Destructor Elapsed: "
                  << std::chrono::duration_cast<Resolution>( end - mStart ).count()
                  << std::endl;
        std::cout << strStream.str() << std::endl;
    }    

    inline void stop() {
        const auto end = Clock::now();
        std::ostringstream strStream;
        strStream << "Stop Elapsed: "
                  << std::chrono::duration_cast<Resolution>(end - mStart).count()
                  << std::endl;
        std::cout << strStream.str() << std::endl;
    }

}; // ExecutionTimer

#endif // EXECUTION_TIMER_H

Hier sind einige Verwendungen davon:

int main() {
    { // empty scope to display ExecutionTimer's destructor's message
         // displayed in milliseconds
         ExecutionTimer<std::chrono::milliseconds> timer;

         // function or code block here

         timer.stop();

    } 

    { // same as above
        ExecutionTimer<std::chrono::microseconds> timer;

        // code block here...

        timer.stop();
    }

    {  // same as above
       ExecutionTimer<std::chrono::nanoseconds> timer;

       // code block here...

       timer.stop();

    }

    {  // same as above
       ExecutionTimer<std::chrono::seconds> timer;

       // code block here...

       timer.stop();

    }              

    return 0;
}

Da es sich bei der Klasse um eine Vorlage handelt, können wir ganz einfach festlegen, wie unsere Zeit gemessen und angezeigt werden soll. Dies ist eine sehr praktische Vorlage für Utility-Klassen zum Benchmarking und sehr einfach zu verwenden.


Persönlich wird die stop()Mitgliedsfunktion nicht benötigt, da der Destruktor den Timer für Sie stoppt.
Casey

@Casey Das Design der Klasse benötigt nicht unbedingt die Stoppfunktion, ist jedoch aus einem bestimmten Grund vorhanden. Das Standardkonstrukt beim Erstellen des Objekts, bevor Sie test codeden Timer starten. Anschließend verwenden test codeSie explizit das Timer-Objekt und rufen dessen Stop-Methode auf. Sie müssen es manuell aufrufen, wenn Sie stopden Timer verwenden möchten . Die Klasse akzeptiert keine Parameter. Auch wenn Sie diese Klasse so verwendet haben, wie ich es gezeigt habe, werden Sie feststellen, dass zwischen dem Aufruf von obj.stopund seiner Klasse nur eine minimale Zeitspanne vergeht destructor.
Francis Cugler

@Casey ... Dies ermöglicht es auch, mehrere Timer-Objekte innerhalb desselben Bereichs zu haben, nicht dass man es wirklich brauchen würde, sondern nur eine weitere praktikable Option.
Francis Cugler

Dieses Beispiel kann in der dargestellten Form nicht kompiliert werden. Der Fehler hängt mit "Keine Übereinstimmung für Operator << ..." zusammen!
Celdor

@Celdor müssen Sie entsprechende Includes; wie <chrono>?
Francis Cugler

0

Ich empfehle die Verwendung, steady_clockdie im Gegensatz zu monoton garantiert ist high_resolution_clock.

#include <iostream>
#include <chrono>

using namespace std;

unsigned int stopwatch()
{
    static auto start_time = chrono::steady_clock::now();

    auto end_time = chrono::steady_clock::now();
    auto delta    = chrono::duration_cast<chrono::microseconds>(end_time - start_time);

    start_time = end_time;

    return delta.count();
}

int main() {
  stopwatch(); //Start stopwatch
  std::cout << "Hello World!\n";
  cout << stopwatch() << endl; //Time to execute last line
  for (int i=0; i<1000000; i++)
      string s = "ASDFAD";
  cout << stopwatch() << endl; //Time to execute for loop
}

Ausgabe:

Hello World!
62
163514

0

Sie können eine einfache Klasse haben, die für diese Art von Messungen verwendet werden kann.

class duration_printer {
public:
    duration_printer() : __start(std::chrono::high_resolution_clock::now()) {}
    ~duration_printer() {
        using namespace std::chrono;
        high_resolution_clock::time_point end = high_resolution_clock::now();
        duration<double> dur = duration_cast<duration<double>>(end - __start);
        std::cout << dur.count() << " seconds" << std::endl;
    }
private:
    std::chrono::high_resolution_clock::time_point __start;
};

Sie müssen lediglich zu Beginn dieser Funktion ein Objekt in Ihrer Funktion erstellen

void veryLongExecutingFunction() {
    duration_calculator dc;
    for(int i = 0; i < 100000; ++i) std::cout << "Hello world" << std::endl;
}

int main() {
    veryLongExecutingFunction();
    return 0;
}

und das ist es. Die Klasse kann an Ihre Anforderungen angepasst werden.


0

Da keine der bereitgestellten Antworten sehr genau ist oder reproduzierbare Ergebnisse liefert, habe ich beschlossen, meinem Code einen Link hinzuzufügen, der eine Genauigkeit von weniger als einer Nanosekunde und wissenschaftliche Statistiken aufweist.

Beachten Sie, dass dies nur zum Messen von Code funktioniert, dessen Ausführung (sehr) kurze Zeit in Anspruch nimmt (auch bekannt als einige Taktzyklen bis zu einigen Tausend): Wenn sie so lange laufen, dass sie wahrscheinlich durch einen -heh- Interrupt unterbrochen werden dann ist es eindeutig nicht möglich, ein reproduzierbares und genaues Ergebnis zu liefern; Die Folge davon ist, dass die Messung niemals beendet wird: Sie misst weiter, bis statistisch zu 99,9% sicher ist, dass sie die richtige Antwort hat, was auf einem Computer, auf dem andere Prozesse ausgeführt werden, niemals geschieht, wenn der Code zu lange dauert.

https://github.com/CarloWood/cwds/blob/master/benchmark.h#L40


0

Wenn Sie Zeit und Codezeilen sparen möchten, können Sie die Messung der Funktionsausführungszeit zu einem einzeiligen Makro machen:

a) Implementiere eine Zeitmessklasse wie oben bereits vorgeschlagen (hier ist meine Implementierung für Android):

class MeasureExecutionTime{
private:
    const std::chrono::steady_clock::time_point begin;
    const std::string caller;
public:
    MeasureExecutionTime(const std::string& caller):caller(caller),begin(std::chrono::steady_clock::now()){}
    ~MeasureExecutionTime(){
        const auto duration=std::chrono::steady_clock::now()-begin;
        LOGD("ExecutionTime")<<"For "<<caller<<" is "<<std::chrono::duration_cast<std::chrono::milliseconds>(duration).count()<<"ms";
    }
};

b) Fügen Sie ein praktisches Makro hinzu, das den aktuellen Funktionsnamen als TAG verwendet (die Verwendung eines Makros ist hier wichtig, andernfalls __FUNCTION__wird MeasureExecutionTimeanstelle der zu messenden Funktion ausgewertet

#ifndef MEASURE_FUNCTION_EXECUTION_TIME
#define MEASURE_FUNCTION_EXECUTION_TIME const MeasureExecutionTime measureExecutionTime(__FUNCTION__);
#endif

c) Schreiben Sie Ihr Makro am Anfang der Funktion, die Sie messen möchten. Beispiel:

 void DecodeMJPEGtoANativeWindowBuffer(uvc_frame_t* frame_mjpeg,const ANativeWindow_Buffer& nativeWindowBuffer){
        MEASURE_FUNCTION_EXECUTION_TIME
        // Do some time-critical stuff 
}

Was zu folgender Ausgabe führt:

ExecutionTime: For DecodeMJPEGtoANativeWindowBuffer is 54ms

Beachten Sie, dass dies (wie alle anderen vorgeschlagenen Lösungen) die Zeit zwischen dem Aufruf Ihrer Funktion und der Rückgabe misst, nicht unbedingt die Zeit, zu der Ihre CPU die Funktion ausgeführt hat. Wenn Sie dem Scheduler jedoch keine Änderung zum Anhalten Ihres laufenden Codes durch Aufrufen von sleep () oder ähnlichem geben, gibt es keinen Unterschied zwischen.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.