سؤال

أحاول استخدام إحصائيات "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
هل كانت مفيدة؟

المحلول

ما هو الغرض من:

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

أعتقد أنك تريد أهم ثلاثة أرقام من usec؛في هذه الحالة، الطريقة الأكثر وضوحًا التي يمكنني التفكير فيها هي قسمة usec على 1000، والانتهاء من ذلك.

حالات تجريبية:

  • 999999 ⇒ 999
  • 99999 ⇒ 999 (يجب أن يكون 099)
  • 9999 ⇒ 999 (يجب أن يكون 009)
  • 999 ⇒ 999 (يجب أن يكون 000)

نصائح أخرى

أعتقد أنه من المحتمل أن يكون هناك خطأ في مكان ما في تكوينك للثانية والاستخدام.لا أستطيع حقًا أن أقول ما هو بالضبط دون معرفة أنواع الأخطاء التي تراها.قد يكون التخمين التقريبي هو أن usec لا يمكن أبدًا أن يكون> ​​999999، لذا فأنت تعتمد على الفائض لمعرفة متى يتم ضبط sec.قد يكون ذلك أيضًا مجرد مشكلة في تنسيق إخراج المدة.

على أي حال.لماذا لا تقوم بتخزين مكونات utime وstime كثواني عائمة بدلاً من محاولة بناء أسلوبك الخاص على الإخراج؟أنا متأكد من أن ما يلي سيمنحك الثواني المناسبة.

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

إذا كنت ترغب في تحليل هذا مرة أخرى إلى شكل جديد، فيمكنك دائمًا استخدام int-div وmodulo.

@ كريس:

أعتقد أنك تريد الأرقام الثلاثة الأكثر أهمية في الاستخدام

نعم.العدد الإجمالي للأرقام في usec يختلف وأريد خفض تلك التي تقل عن 1000.على سبيل المثال، إذا usec=1000, ، أريد الحصول على النتيجة 100 (وليس 1 كما تقترح).لذلك، لا أستطيع ببساطة القسمة على 1000.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top