baidu_time_unittest.cpp 6.26 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.
gejun's avatar
gejun committed
17 18

#include <gtest/gtest.h>
gejun's avatar
gejun committed
19 20 21
#include "butil/build_config.h"

#if defined(OS_LINUX)
gejun's avatar
gejun committed
22 23
#include <syscall.h>                         // SYS_clock_gettime
#include <unistd.h>                          // syscall
gejun's avatar
gejun committed
24 25
#endif

26 27 28
#include "butil/time.h"
#include "butil/macros.h"
#include "butil/logging.h"
gejun's avatar
gejun committed
29 30 31 32

namespace {

TEST(BaiduTimeTest, diff_between_gettimeofday_and_REALTIME) {
33
    long t1 = butil::gettimeofday_us();
gejun's avatar
gejun committed
34 35
    timespec time;
    clock_gettime(CLOCK_REALTIME, &time);
36
    long t2 = butil::timespec_to_microseconds(time);
gejun's avatar
gejun committed
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
    LOG(INFO) << "t1=" << t1 << " t2=" << t2;
}

const char* clock_desc[] = {
    "CLOCK_REALTIME",                 //0
    "CLOCK_MONOTONIC",                //1
    "CLOCK_PROCESS_CPUTIME_ID",       //2
    "CLOCK_THREAD_CPUTIME_ID",        //3
    "CLOCK_MONOTONIC_RAW",            //4
    "CLOCK_REALTIME_COARSE",          //5
    "CLOCK_MONOTONIC_COARSE",         //6
    "CLOCK_BOOTTIME",                 //7
    "CLOCK_REALTIME_ALARM",           //8
    "CLOCK_BOOTTIME_ALARM",           //9
    "CLOCK_SGI_CYCLE",                //10
    "CLOCK_TAI"                       //11
};

TEST(BaiduTimeTest, cost_of_timer) {
    printf("sizeof(time_t)=%lu\n", sizeof(time_t));
    
58
    butil::Timer t1, t2;
gejun's avatar
gejun committed
59 60 61 62 63 64 65
    timespec ts;
    const size_t N = 200000;
    t1.start();
    for (size_t i = 0; i < N; ++i) {
        t2.stop();
    }
    t1.stop();
gejun's avatar
gejun committed
66
    printf("Timer::stop() takes %" PRId64 "ns\n", t1.n_elapsed() / N);
gejun's avatar
gejun committed
67 68 69 70 71 72

    t1.start();
    for (size_t i = 0; i < N; ++i) {
        clock();
    }
    t1.stop();
gejun's avatar
gejun committed
73
    printf("clock() takes %" PRId64 "ns\n", t1.n_elapsed() / N);
gejun's avatar
gejun committed
74 75 76 77

    long s = 0;
    t1.start();
    for (size_t i = 0; i < N; ++i) {
78
        s += butil::cpuwide_time_ns();
gejun's avatar
gejun committed
79 80
    }
    t1.stop();
gejun's avatar
gejun committed
81
    printf("cpuwide_time() takes %" PRId64 "ns\n", t1.n_elapsed() / N);
gejun's avatar
gejun committed
82 83 84

    t1.start();
    for (size_t i = 0; i < N; ++i) {
85
        s += butil::gettimeofday_us();
gejun's avatar
gejun committed
86 87
    }
    t1.stop();
gejun's avatar
gejun committed
88
    printf("gettimeofday_us takes %" PRId64 "ns\n", t1.n_elapsed() / N);
89

gejun's avatar
gejun committed
90 91
    t1.start();
    for (size_t i = 0; i < N; ++i) {
92
        time(NULL);
gejun's avatar
gejun committed
93 94
    }
    t1.stop();
gejun's avatar
gejun committed
95
    printf("time(NULL) takes %" PRId64 "ns\n", t1.n_elapsed() / N);
gejun's avatar
gejun committed
96 97 98

    t1.start();
    for (size_t i = 0; i < N; ++i) {
99
        s += butil::monotonic_time_ns();
gejun's avatar
gejun committed
100 101
    }
    t1.stop();
gejun's avatar
gejun committed
102
    printf("monotonic_time_ns takes %" PRId64 "ns\n", t1.n_elapsed() / N);
gejun's avatar
gejun committed
103 104

    for (size_t i = 0; i < arraysize(clock_desc); ++i) {
gejun's avatar
gejun committed
105
#if defined(OS_LINUX)
gejun's avatar
gejun committed
106 107 108 109 110 111
        if (0 == syscall(SYS_clock_gettime, (clockid_t)i, &ts)) {
            t1.start();
            for (size_t j = 0; j < N; ++j) {
                syscall(SYS_clock_gettime, (clockid_t)i, &ts);
            }
            t1.stop();
gejun's avatar
gejun committed
112
            printf("sys   clock_gettime(%s) takes %" PRId64 "ns\n",
gejun's avatar
gejun committed
113 114
                   clock_desc[i], t1.n_elapsed() / N);
        }
gejun's avatar
gejun committed
115
#endif
gejun's avatar
gejun committed
116 117 118 119 120 121
        if (0 == clock_gettime((clockid_t)i, &ts)) {
            t1.start();
            for (size_t j = 0; j < N; ++j) {
                clock_gettime((clockid_t)i, &ts);
            }
            t1.stop();
gejun's avatar
gejun committed
122
            printf("glibc clock_gettime(%s) takes %" PRId64 "ns\n",
gejun's avatar
gejun committed
123 124 125 126 127 128 129
                   clock_desc[i], t1.n_elapsed() / N);
        }
    }
}

TEST(BaiduTimeTest, timespec) {
    timespec ts1 = { 0, -1 };
130
    butil::timespec_normalize(&ts1);
gejun's avatar
gejun committed
131 132 133 134
    ASSERT_EQ(999999999L, ts1.tv_nsec);
    ASSERT_EQ(-1, ts1.tv_sec);

    timespec ts2 = { 0, 1000000000L };
135
    butil::timespec_normalize(&ts2);
gejun's avatar
gejun committed
136 137 138 139
    ASSERT_EQ(0L, ts2.tv_nsec);
    ASSERT_EQ(1L, ts2.tv_sec);

    timespec ts3 = { 0, 999999999L };
140
    butil::timespec_normalize(&ts3);
gejun's avatar
gejun committed
141 142 143 144
    ASSERT_EQ(999999999L, ts3.tv_nsec);
    ASSERT_EQ(0, ts3.tv_sec);

    timespec ts4 = { 0, 1L };
145
    butil::timespec_add(&ts4, ts3);
gejun's avatar
gejun committed
146 147 148 149
    ASSERT_EQ(0, ts4.tv_nsec);
    ASSERT_EQ(1L, ts4.tv_sec);

    timespec ts5 = { 0, 999999999L };
150
    butil::timespec_minus(&ts5, ts3);
gejun's avatar
gejun committed
151 152 153 154
    ASSERT_EQ(0, ts5.tv_nsec);
    ASSERT_EQ(0, ts5.tv_sec);

    timespec ts6 = { 0, 999999998L };
155
    butil::timespec_minus(&ts6, ts3);
gejun's avatar
gejun committed
156 157 158
    ASSERT_EQ(999999999L, ts6.tv_nsec);
    ASSERT_EQ(-1L, ts6.tv_sec);

159
    timespec ts7 = butil::nanoseconds_from(ts3, 1L);
gejun's avatar
gejun committed
160 161 162
    ASSERT_EQ(0, ts7.tv_nsec);
    ASSERT_EQ(1L, ts7.tv_sec);

163
    timespec ts8 = butil::nanoseconds_from(ts3, -1000000000L);
gejun's avatar
gejun committed
164 165 166
    ASSERT_EQ(999999999L, ts8.tv_nsec);
    ASSERT_EQ(-1L, ts8.tv_sec);

167
    timespec ts9 = butil::microseconds_from(ts3, 1L);
gejun's avatar
gejun committed
168 169 170
    ASSERT_EQ(999L, ts9.tv_nsec);
    ASSERT_EQ(1L, ts9.tv_sec);

171
    timespec ts10 = butil::microseconds_from(ts3, -1000000L);
gejun's avatar
gejun committed
172 173 174
    ASSERT_EQ(999999999L, ts10.tv_nsec);
    ASSERT_EQ(-1L, ts10.tv_sec);

175
    timespec ts11 = butil::milliseconds_from(ts3, 1L);
gejun's avatar
gejun committed
176 177 178
    ASSERT_EQ(999999L, ts11.tv_nsec);
    ASSERT_EQ(1L, ts11.tv_sec);

179
    timespec ts12 = butil::milliseconds_from(ts3, -1000L);
gejun's avatar
gejun committed
180 181 182
    ASSERT_EQ(999999999L, ts12.tv_nsec);
    ASSERT_EQ(-1L, ts12.tv_sec);

183
    timespec ts13 = butil::seconds_from(ts3, 1L);
gejun's avatar
gejun committed
184 185 186
    ASSERT_EQ(999999999L, ts13.tv_nsec);
    ASSERT_EQ(1, ts13.tv_sec);

187
    timespec ts14 = butil::seconds_from(ts3, -1L);
gejun's avatar
gejun committed
188 189 190 191 192
    ASSERT_EQ(999999999L, ts14.tv_nsec);
    ASSERT_EQ(-1L, ts14.tv_sec);
}

TEST(BaiduTimeTest, every_many_us) {
193
    butil::EveryManyUS every_10ms(10000L);
gejun's avatar
gejun committed
194
    size_t i = 0;
195
    const long start_time = butil::gettimeofday_ms();
gejun's avatar
gejun committed
196 197
    while (1) {
        if (every_10ms) {
gejun's avatar
gejun committed
198
            printf("enter this branch at %" PRId64 "ms\n",
199
                   butil::gettimeofday_ms() - start_time);
gejun's avatar
gejun committed
200 201 202 203 204 205 206 207
            if (++i >= 10) {
                break;
            }
        }
    }
}

TEST(BaiduTimeTest, timer_auto_start) {
208
    butil::Timer t(butil::Timer::STARTED);
gejun's avatar
gejun committed
209 210
    usleep(100);
    t.stop();
gejun's avatar
gejun committed
211
    printf("Cost %" PRId64 "us\n", t.u_elapsed());
gejun's avatar
gejun committed
212 213
}

214
} // namespace