質問
プログラムで「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 の最上位 3 桁が必要だと思います。この場合、私が考える最も簡単な方法は、usec を 1000 で割ってそれで完了することです。
テストケース:
- 999999 ⇒ 999
- 99999 ⇒ 999 (099 である必要があります)
- 9999 ⇒ 999 (009 である必要があります)
- 999 ⇒ 999 (000 である必要があります)
他のヒント
おそらく sec と usec の構成のどこかにバグがあると思います。発生しているエラーの種類がわからないと、正確に何とも言えません。大まかに推測すると、usec が 999999 を超えることはありえないため、秒を調整するタイミングを知るためにオーバーフローに依存していることになります。また、単に期間の出力形式に問題がある可能性もあります。
ともかく。出力時に独自の rusage を構築するのではなく、utime コンポーネントと stime コンポーネントを float 秒として保存してはどうでしょうか?以下のようにすれば適切な秒数が得られると確信しています。
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 を実行できます。
@クリス:
usec の最上位 3 桁が必要だと思います
はい。全体の桁数 usec
変動するので、それらを 1000 未満に削減したいと考えています。たとえば、次の場合 usec=1000
, 、結果100を取得したいと考えています(あなたが提案しているように、1ではありません)。したがって、単純に 1000 で割ることはできません。