0

I'm using chrono library. My code looks like:

auto begin = chrono::high_resolution_clock::now();
// operations
auto end = chrono::high_resolution_clock::now();
auto elapsed = chrono::duration_cast<chrono::nanoseconds>(end - begin);
cout<<”time: „<<elapsed.count()<<endl;

And it always shows 0. What am I doing wrong?

ktoś tam
  • 1
  • 1
  • Maybe the code in the //operations was optimized out because it did not do anything useful – drescherjm May 30 '21 at 15:47
  • Use `steady_clock` for measuring. `high_resolution_clock` isn't necessarily monotonic. – chris May 30 '21 at 15:47
  • 1
    You have the wrong quotation marks in your example code. – drescherjm May 30 '21 at 15:47
  • it was searching value in the red-black tree, I can't believe it is that fast – ktoś tam May 30 '21 at 15:48
  • Maybe the optimizer decided the search was not needed at all because you didn't use the result. Related: [https://en.cppreference.com/w/cpp/language/as_if](https://en.cppreference.com/w/cpp/language/as_if) – drescherjm May 30 '21 at 15:49
  • Clock resolution could easily be 0.01 second, have you made enough runs of you algorithm between the two time points? – bipll May 30 '21 at 15:50
  • @chris I modified high_resolution to steady. Now it shows 78100 nanoseconds. Could you explain why is it so with those 2 clocks? What's the difference between them? – ktoś tam May 30 '21 at 17:27
  • @ktośtam, `steady_clock` is monotonic. `system_clock` is based on the human time (what you see when you look at the time). `high_resolution_clock` is an alias of either of those two or some other clock if the implementation decides so. It's quite possible that `high_resolution_clock` is `system_clock` for you and that `steady_clock` uses a clock based on rdtsc, which (ironically in this case) offers more resolution than `system_clock`. Resolution aside, you don't want DST, NTP syncs, or the user changing the time to affect your measurements. – chris May 30 '21 at 17:41

1 Answers1

0

To measure the difference between two times, save the difference in the appropriate object based on the precision you want:

std::chrono::duration<double, std::milli> fp_ms = end - start;//difference in milliseconds
std::chrono::duration<double, std::nano> fp_ns = end - start;//difference in nanoseconds

Then, you can convert this to seconds appropriately (or better yet, use the default in seconds duration<double> suggestion made by user chris in comments):

Live on Compiler Explorer

#include <iostream>
#include <chrono>
int main() {
    auto V = std::chrono::high_resolution_clock::now();
    for(int i = 0; i < 2000; i++)
        printf("%d ", i);
    printf("\n");
    auto Y = std::chrono::high_resolution_clock::now();
    std::chrono::duration<double> fp_s = Y - V;
    std::chrono::duration<double, std::milli> fp_ms = Y - V;
    std::chrono::duration<double, std::nano> fp_ns = Y - V;
    auto Zm = fp_ms.count()/1000.;
    auto Zn = fp_ns.count()/1000000000.;
    std::cout<<"Time from seconds in seconds is " << fp_s.count()<<std::endl;
    std::cout<<"Time from milliseconds in seconds is "<< Zm <<std::endl;
    std::cout<<"Time from nanoseconds in seconds is "<< Zn << std::endl;
//OP's method:
    auto elapsed = std::chrono::duration_cast<std::chrono::nanoseconds>(Y - V);
    std::cout<<"time: "<<elapsed.count()<<std::endl;
}

By the way, your method also works. See compiler explorer link above.

Tryer
  • 3,580
  • 1
  • 26
  • 49
  • still counts 0, it' s impossible to be faster than 1ns – ktoś tam May 30 '21 at 16:12
  • It is also important to not that while chrono offers nanosecond resolution few systems at this time can provide it. If you are using modern desktop hardware you can forget about anything below microseconds and even milliseconds will be dodgy. – user4581301 May 30 '21 at 16:12
  • 2
    You shouldn't escape the chrono type system to do your own unit conversions. Chrono comes equipped with safe conversions already. If you want the answer in seconds, use `duration` and let it handle the conversion. – chris May 30 '21 at 16:13
  • 1
    [A note on `high_resolution_clock` from one of the people most responsible for it.](https://stackoverflow.com/a/37440647/4581301) – user4581301 May 30 '21 at 16:18
  • I've tried on two computers and on both it shows 0 nanoseconds :( – ktoś tam May 30 '21 at 16:35
  • @chris yes thanks. I have made that change in the code and the answer. – Tryer May 30 '21 at 16:47
  • @ktośtam, You still haven't addressed the comments concerned about what you're actually measuring after the compiler is done with it. The question still contains `// operations` in place of the important part and no assembly output. – chris May 30 '21 at 16:48
  • @user4581301 Thanks for the link. So, the writer himself says `steady_clock` is to be preferred to `high_resolution_clock`. I have a bunch of find and replaces to do in my code base! – Tryer May 30 '21 at 17:00