Статистика «rusage»

Я пытаюсь использовать статистику «rusage» в своей программе, чтобы получить данные, аналогичные данным инструмента время. Однако я почти уверен, что делаю что-то не так. Значения кажутся примерно правильными, но временами могут быть немного странными. Я не нашел хороших ресурсов в Интернете. Кто-нибудь знает, как это сделать лучше?

Извините за длинный код.

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
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
0
2 739
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Я думаю, что где-то в вашем составе sec и usec есть ошибка. Я не могу точно сказать, что именно, не зная, какие ошибки вы видите. Приблизительно предположим, что usec никогда не может быть> 999999, поэтому вы полагаетесь на переполнение, чтобы знать, когда настраивать sec. Это также может быть проблема с вашим форматом вывода продолжительности.

Так или иначе. Почему бы не сохранить компоненты utime и stime в виде секунд с плавающей запятой вместо того, чтобы пытаться создать свой собственный rusage на выходе? Я почти уверен, что следующее даст вам правильные секунды.

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);
}

Если вы хотите разложить это обратно на rusage, вы всегда можете int-div и modulo.

Ответ принят как подходящий

Какова цель:

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

Я так понимаю, вам нужны три старшие цифры usec; в этом случае самый простой способ, который я могу придумать, - это разделить мксек на 1000 и покончить с этим.

Тестовые случаи:

  • 999999 ⇒ 999.
  • 99999 ⇒ 999 (должно быть 099)
  • 9999 ⇒ 999 (должно быть 009)
  • 999 ⇒ 999 (должно быть 000).

@Крис:

I gather that you want the most significant three digits of the usec

Да. Общее количество цифр в usec варьируется, и я хочу сократить число цифр ниже 1000. Например, если usec=1000, я хочу получить результат 100 (а не 1, как вы предлагаете). Следовательно, я не могу просто разделить на 1000.

Я не уверен, что вы имеете в виду, говоря, что количество используемых цифр меняется. Насколько мне известно, все значения в нем должны быть от 0 до 999 999, что соответствует 0 мс и 999,999 мс соответственно. «Старшие три цифры» для меня означало, что вам нужен счет в миллисекундах. Я что-то не так прочитал?

Chris Jester-Young 18.09.2008 14:24

Крис, тег @, похоже, в любом случае не работает. По поводу вашего комментария: я больше не работаю над этим кодом и больше не уверен, что именно я хотел получить. : - / AFAIR Я хотел посчитать 999 чисел в вашем ответе, то есть нет те, которые вы указали как «должно быть». Теперь я думаю, ты был прав.

Konrad Rudolph 13.10.2008 13:54

Другие вопросы по теме