Clock() vs time() vs std::chrono::high_resolution_clock

I believe that chrono::high_resolution is the more correct and modern way of measuring time with C++ whilst clock() and time() are the old ways of getting/measuring time with C.
Anyways is any one version better than the other or should any one be used over the other? Does one have more features than the other? I know that using chrono is now the standard way of doing this and is accurate to nano seconds. However like I said should the other options ever be used again or only when dealing with C.
time() outputs a Unix timestamp, which is the format used in everything. Not to mention how easy it is to do calculations with it.
I believe that chrono::high_resolution is the more correct and modern way of measuring time with C++ whilst clock() and time() are the old ways of getting/measuring time with C.


Realise that std::chrono::high_resolution_clock is a wall clock, and is not suitable for execution timing of programs. On the other hand std::clock is good for that.

You can read about them here:

http://en.cppreference.com/w/cpp/chrono
http://en.cppreference.com/w/cpp/chrono/c/clock
Ah okay @TheIdeasMan would std::chrono::steady_clock be more relatable for std::clock than higher_resolution_clock? On this website it says this about it, "steady_clock is specifically designed to calculate time intervals." So I assume it is? If so should I use that over std::clock or no?

EDIT: I read your response wrong @TheIdeasMan I confused execution timing with timing algorithms and random things within a program. I think.
Last edited on
EDIT: I read your response wrong @TheIdeasMan I confused execution timing with timing algorithms and random things within a program. I think.


By execution timing, I meant timing of algorithms.

What do you want to do?

If you want to make your own clock app, or time something external in real time (a stopwatch), then I imagine steady_clock would be good for that. It provides consistent results even though an external clock (The one in your computer) may be adjusted.

http://en.cppreference.com/w/cpp/chrono/high_resolution_clock
cppreference wrote:
Class std::chrono::high_resolution_clock represents the clock with the smallest tick period provided by the implementation. It may be an alias of std::chrono::system_clock or std::chrono::steady_clock, or a third, independent clock.


cppreference wrote:
]constexpr bool is_steady
[static]
true if the time between ticks is always constant, i.e. calls to now() return values that increase monotonically even in case of some external clock adjustment


> would std::chrono::steady_clock be more relatable for std::clock than higher_resolution_clock?

std::chrono::high_resolution_clock is not required to be a monotonic clock; std::chrono::high_resolution_clock::is_steady need not be true.

To reliably measure time intervals, we need a clock with the time between ticks guaranteed to be constant, with time points increasing monotonically.

To get the clock with the highest available resolution, suitable for reliably measuring elapsed time:
1
2
3
4
// #include <type_traits>
using clock_type = typename std::conditional< std::chrono::high_resolution_clock::is_steady,
                                              std::chrono::high_resolution_clock,
                                              std::chrono::steady_clock >::type ;
Last edited on
@TheIdeasMan I'm more or less trying to make a timer class for my game. So in that class I want to be able to have a special amount of time so that every 30 seconds(or whatever time the class is initialized with) the function will return true and a special drop will appear or whatever I'm using the time for. So I need a timer that does that. I also was trying to make a timer that count downs from say, 60-0 seconds, and once that it reaches 0 stop the game. Oh and I also would like to be displaying the time on screen in which I'd do that via overloading the << operator. Would you recommend steady_clock for that? Or something else?

@JLBorges I have never seen that type of code been done before, especially that std::conditional< with a bunch of values. Guess I'm going to have to do some learning.

Thanks for the responses so far!
Last edited on
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include <iostream>
#include <chrono>
#include <type_traits>
#include <thread>

namespace time_utils
{
    using clock_type = typename std::conditional< std::chrono::high_resolution_clock::is_steady,
                                                  std::chrono::high_resolution_clock,
                                                  std::chrono::steady_clock >::type ;
                                                  
    // after every 'interval_millisecs' milliseconds, call function 'fn'; repeat 'count' times
    template< typename FN > void periodic_repeat( FN fn, unsigned int interval_millisecs, unsigned int count )
    {
        for( unsigned int i = 0 ; i < count ; ++i )
        {
            std::this_thread::sleep_for( std::chrono::milliseconds(interval_millisecs) ) ;
            fn() ;
        }
    }

    struct curr_time {} current_time ;
    std::ostream& operator<< ( std::ostream& stm, curr_time )
    {
        const auto now = std::time(nullptr) ;
        return stm << std::ctime( std::addressof(now) ) ;
    }
}

int main()
{
    std::cout << "program start: " << time_utils::current_time ;
    
    const auto start = time_utils::clock_type::now() ;
    time_utils::periodic_repeat( [] { std::cout << " current time: " << time_utils::current_time ; }, 2000, 5 ) ;
    const auto end = time_utils::clock_type::now() ;

    std::cout << "elapsed: " << std::chrono::duration_cast<std::chrono::seconds>(end-start).count() << " seconds.\n" ;
}

http://coliru.stacked-crooked.com/a/1cc3a0c41d6ea84f
I tried compiling that on visual studio and well it gave me an error?
line 8:typename cannot be used outside a template declaration

Why is that it will compile on cpp.sh yet not on VS studio?

Btw I added ctime because visual studio required it for std::time and std::ctime.
Last edited on
> Why is that it will compile on cpp.sh yet not on VS studio?

Visual Studio 2015 allows this C++11 construct. http://rextester.com/SKOYP18066
Consider upgrading to the current version of Visual Studio

In legacy C++, the keyword typename was not allowed other than within templates; C++11 relaxed this rule.

This would work everywhere:
1
2
3
using clock_type = /*typename*/ std::conditional< std::chrono::high_resolution_clock::is_steady,
                                                  std::chrono::high_resolution_clock,
                                                  std::chrono::steady_clock >::type ;



> I added ctime because visual studio required it for std::time and std::ctime.

Yes. <ctime> is required for std::time and std::ctime.
Last edited on
@JLBorges I swear I have the latest version of VS. It's VS Community 2015 and well it wouldn't work there. I'll have to check later as I can't right now.

I have a question on a few lines of the code though. Specifically what exactly is FN fn supposed to be for on line 13? I know its a template parameter but what is its purpose in the code? And why is fn() being called in the for loop? Wouldn't the loop sleep for its amount of time without it being called? Also I can't find its declaration in the code(fn())?

Another thing is you input [] as the first parameter, presumably for the FN fn parameter and well I've never seen that? What is that supposed to be doing?
> I have the latest version of VS. It's VS Community 2015

What does std::cout << _MSC_FULL_VER << '\n' ; print out?


> what exactly is FN fn supposed to be for on line 13

In
1
2
// after every 'interval_millisecs' milliseconds, call function 'fn'; repeat 'count' times
template< typename FN > void periodic_repeat( FN fn, unsigned int interval_millisecs, unsigned int count )

The type FN is a function object type;
and fn is a function object - an object that can be used on the left side of a function call operator.

periodic_repeat() repeatedly calls the function fn at periodic intervals.


> Wouldn't the loop sleep for its amount of time without it being called?

Yes; it would. std::this_thread::sleep_for( std::chrono::milliseconds(interval_millisecs) ) ; would block the execution of the current thread for at least 'interval_millisecs' milliseconds.


> you input [] as the first parameter, presumably for the FN fn parameter

The first argument [] { std::cout << " current time: " << time_utils::current_time ; } is a lambda expression. The evaluation of a lambda expression results in a function object.
See: https://msdn.microsoft.com/en-us/library/dd293608.aspx
@JLBorges
What does std::cout << _MSC_FULL_VER << '\n' ; print out?

It prints 190023026

Something worth mentioning is that a ton of other c++ 11/14 features work such as nullptr, constexpr, default variable values in a class, auto, ranged base loops, 0b/binary support, multi-threading, unique_ptr, enum class/struct with initializer type, etc.

periodic_repeat() repeatedly calls the function fn at periodic intervals.

Why though?
I removed to see what it did and well it only displayed the time once. Apparently disabling that makes it display less times, one time to be exact.
Also another error has occured:

Error C4996 'ctime': This function or variable may be unsafe. Consider using ctime_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS.


So apparently ctime has been deprecated. Thus I tried ctime_s and well now it doesn't except an arguement of std::adressof(now));

The first argument [] { std::cout << " current time: " << time_utils::current_time ; } is a lambda expression. The evaluation of a lambda expression results in a function object.

Anyways I knew I recognized that kind of syntax from somwhere sort of just wasn't sure and yep it was a lambda. Weirdest looking thing of the language lol, eh i'll get used to it. Anyways I'll read up on it.

Thanks!
Last edited on
> What does std::cout << _MSC_FULL_VER << '\n' ; print out?
> It prints 190023026

An integer made up of the major version, the minor version, and the build number of the compiler.
For instance, 190023026: major version is 19, minor version is 00, and build number is 23026.
https://msdn.microsoft.com/en-us/library/b0084kay.aspx


This is the C++ compiler that shipped with the original release of Visual Studio 2015.
It has subsequently been updated; with update 1, _MSC_FULL_VER would be 190023506 (build number 23506). With the updated compiler, the original code compiles cleanly. http://rextester.com/BPK68326

Note: Update 2 has just been released. https://www.visualstudio.com/en-us/news/vs2015-update2-vs.aspx


> periodic_repeat() repeatedly calls the function fn at periodic intervals.
>> Why though?

Well, the idea of periodic_repeat() is to execute some piece of code at periodic intervals.
To merely block execution (wait), for say 15 seconds, this would suffice:
std::this_thread::sleep_for( std::chrono::seconds(15) ) ;


> This function or variable may be unsafe. Consider using ctime_s instead.
> To disable deprecation, use _CRT_SECURE_NO_WARNINGS.
> So apparently ctime has been deprecated.

std::ctime() is not deprecated; it is a standard library function.

It has some limitations:
This function returns a pointer to static data and is not thread-safe. In addition, it modifies the static std::tm object which may be shared with std::gmtime and std::localtime. POSIX marks this function obsolete and recommends std::strftime instead.
The behavior may be undefined for the values of time_t that result in the string longer than 25 characters (e.g. year 10000)
http://en.cppreference.com/w/cpp/chrono/c/ctime


> Consider using ctime_s instead.

This is preposterous Microsoft nonsense.
If a more robust alternative is required, use the standard function std::strftime()
More information: http://www.cplusplus.com/forum/beginner/170947/
This is the C++ compiler that shipped with the original release of Visual Studio 2015.
It has subsequently been updated; with update 1, _MSC_FULL_VER would be 190023506 (build number 23506).


Well I guess that's a good thing an update/patch has arrived. 2015 and not all of C++ 11's features working :P. Anyways I'll download that soon.

Well, the idea of periodic_repeat() is to execute some piece of code at periodic intervals.
To merely block execution (wait), for say 15 seconds, this would suffice:


Ahh so instead of pretty much completely blocking out all updates/executions it allows you do things within those set timings. Makes sense.

std::ctime() is not deprecated; it is a standard library function.


Yeah I was confused as well. VS tends to have a habit of trying to "fix" C++ std. Pretty annoying, especially since it won't even allow printf/scanf rather printf_s and scanf_s. Same with conio.h getch and khbit, now its getch_s and khbit_s. Seriously visual studio your a good compiler but stop trying to remake the std :P and make it annoying for everyone else :P.

This is preposterous Microsoft nonsense.
If a more robust alternative is required, use the standard function std::strftime()


Yeah I agree, what compiler/IDE do you tend to use? And I'll check out strftime(), jesus VS making everything harder than it needs to be...
> what compiler/IDE do you tend to use?

I tend to use an IDE only on Windows: given a choice, Visual Studio 2015.

Also compile cleanly with the v140_clang_3_7 (Clang with Microsoft CodeGen) tool-chain.
https://blogs.msdn.microsoft.com/vcblog/2015/12/04/clang-with-microsoft-codegen-in-vs-2015-update-1/

Debug: WinDbg front-end (with KD/LKD, CDB, NTSD back-ends)


> VS making everything harder than it needs to be...

Just define _CRT_SECURE_NO_WARNINGS and these warnings would go away.
Perhaps also turn on code analysis with /analyze https://msdn.microsoft.com/en-us/library/ms173498.aspx
Last edited on
Just define _CRT_SECURE_NO_WARNINGS and these warnings would go away.
Perhaps also turn on code analysis with /analyze https://msdn.microsoft.com/en-us/library/ms173498.aspx


Ah okay will do. Anyways thanks. I'll either come back to this post for help or make another post for help if needed.

Thanks to everyone so far!
Topic archived. No new replies allowed.