Frage

Ich versuche, in meinem Programm „Rusage“-Statistiken zu verwenden, um Daten zu erhalten, die denen von ähneln Zeit Werkzeug.Allerdings bin ich mir ziemlich sicher, dass ich etwas falsch mache.Die Werte scheinen ungefähr richtig zu sein, können aber manchmal etwas seltsam sein.Ich habe online keine guten Ressourcen gefunden.Weiß jemand, wie man es besser macht?

Entschuldigung für den langen Code.

class StopWatch {
public:
    void start() {
        getrusage(RUSAGE_SELF, &m_begin);
        gettimeofday(&m_tmbegin, 0);
    }

    void stop() {
        getrusage(RUSAGE_SELF, &m_end);
        gettimeofday(&m_tmend, 0);
        timeval_sub(m_end.ru_utime, m_begin.ru_utime, m_diff.ru_utime);
        timeval_sub(m_end.ru_stime, m_begin.ru_stime, m_diff.ru_stime);
        timeval_sub(m_tmend, m_tmbegin, m_tmdiff);
    }

    void printf(std::ostream& out) const {
        using namespace std;

        timeval const& utime = m_diff.ru_utime;
        timeval const& stime = m_diff.ru_stime;

        format_time(out, utime);
        out << "u ";
        format_time(out, stime);
        out << "s ";
        format_time(out, m_tmdiff);
    }

private:
    rusage m_begin;
    rusage m_end;
    rusage m_diff;
    timeval m_tmbegin;
    timeval m_tmend;
    timeval m_tmdiff;

    static void timeval_add(timeval const& a, timeval const& b, timeval& ret) {
        ret.tv_usec = a.tv_usec + b.tv_usec;
        ret.tv_sec = a.tv_sec + b.tv_sec;
        if (ret.tv_usec > 999999) {
            ret.tv_usec -= 1000000;
            ++ret.tv_sec;
        }
    }

    static void timeval_sub(timeval const& a, timeval const& b, timeval& ret) {
        ret.tv_usec = a.tv_usec - b.tv_usec;
        ret.tv_sec = a.tv_sec - b.tv_sec;
        if (a.tv_usec < b.tv_usec) {
            ret.tv_usec += 1000000;
            --ret.tv_sec;
        }
    }

    static void format_time(std::ostream& out, timeval const& tv) {
        using namespace std;
        long usec = tv.tv_usec;
        while (usec >= 1000)
            usec /= 10;
        out << tv.tv_sec << '.' << setw(3) << setfill('0') << usec;
    }
}; // class StopWatch
War es hilfreich?

Lösung

Was ist der Zweck von:

while (usec >= 1000)
    usec /= 10;

Ich nehme an, dass Sie die höchstwertigen drei Ziffern des usec wollen;In diesem Fall ist der einfachste Weg, den ich mir vorstellen kann, die Division von usec durch 1000 und fertig.

Testfälle:

  • 999999 ⇒ 999
  • 99999 ⇒ 999 (sollte 099 sein)
  • 9999 ⇒ 999 (sollte 009 sein)
  • 999 ⇒ 999 (sollte 000 sein)

Andere Tipps

Ich denke, es gibt wahrscheinlich irgendwo in Ihrer Zusammensetzung von sec und usec einen Fehler.Ich kann nicht wirklich sagen, was genau, ohne zu wissen, welche Art von Fehlern Sie sehen.Eine grobe Vermutung wäre, dass usec niemals > 999999 sein kann, Sie verlassen sich also auf den Überlauf, um zu wissen, wann sec angepasst werden muss.Es könnte auch einfach ein Problem mit Ihrem Dauerausgabeformat sein.

Ohnehin.Warum speichern Sie die utime- und stime-Komponenten nicht als Float-Sekunden, anstatt zu versuchen, Ihre eigene Verwendung für die Ausgabe zu erstellen?Ich bin mir ziemlich sicher, dass das Folgende Ihnen die richtigen Sekunden geben wird.

static int timeval_diff_ms(timeval const& end, timeval const& start) {
    int micro_seconds = (end.tv_sec  - start.tv_sec) * 1000000 
        + end.tv_usec - start.tv_usec;

    return micro_seconds;
}

static float timeval_diff(timeval const& end, timeval const& start) {
    return (timeval_diff_ms(end, start)/1000000.0f);
}

Wenn Sie dies wieder in eine Russage zerlegen möchten, können Sie immer int-div und modulo verwenden.

@Chris:

Ich nehme an, dass Sie die höchstwertigen drei Ziffern des usec wollen

Ja.Die Gesamtzahl der Ziffern in usec variiert und ich möchte diese unter 1000 senken.Zum Beispiel, wenn usec=1000, Ich möchte das Ergebnis 100 erhalten (nicht 1, wie Sie vorschlagen).Deshalb kann ich nicht einfach durch 1000 dividieren.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top