How people used to measure time before chrono? - c++

Since C++11 we can measure time as in https://en.cppreference.com/w/cpp/chrono
#include <iostream>
#include <chrono>
long fibonacci(unsigned n)
{
if (n < 2) return n;
return fibonacci(n-1) + fibonacci(n-2);
}
int main()
{
auto start = std::chrono::steady_clock::now();
std::cout << "f(42) = " << fibonacci(42) << '\n';
auto end = std::chrono::steady_clock::now();
std::chrono::duration<double> elapsed_seconds = end-start;
std::cout << "elapsed time: " << elapsed_seconds.count() << "s\n";
}
How people used to measure time before chrono? Was there a C++ way to do it or people used to reply on OS specific facilities?

Related

How to make std chrono output in milliseconds or nanoseconds? [duplicate]

This question already has answers here:
How to get duration, as int milli's and float seconds from <chrono>?
(5 answers)
Closed 13 days ago.
#include <iostream>
#include <chrono>
using namespace std;
class Time
{
chrono::steady_clock::time_point start;
public:
Time()
{
start = chrono::steady_clock::now();
}
~Time()
{
auto end = chrono::steady_clock::now();
std::chrono::duration<double> time = end-start;
cout << "time " << time.count() << endl;
}
};
void revstr(char* input)
{
int length = strlen(input);
int last_pos = length-1;
for(int i = 0; i < length/2; i++)
{
char tmp = input[i];
input[i] = input[last_pos - i];
input[last_pos - i] = tmp;
}
}
int main()
{
Time t;
char str[] = "abcd";
cout << str << endl;
revstr(str);
cout << str << endl;
}
The above outputs:
time 7.708e-06
How should we turn that in milliseconds, nanoseconds or seconds?
I tried (replace std::chrono::duration<double> time = end-start;)
std::chrono::duration<std::chrono::nanoseconds> time = end-start;
But it says:
A duration representation cannot be a duration.
Use std::chrono::duration_cast():
#include <chrono>
#include <iostream>
int main()
{
std::chrono::duration<double> time{7.708e-06};
auto nanos = std::chrono::duration_cast<std::chrono::nanoseconds>(time);
std::cout << nanos.count() << '\n';
}

Any point in having variable for end time for time measurment?

From std::chrono::system_clock::now in cppreference
#include <iostream>
#include <iomanip>
#include <vector>
#include <numeric>
#include <chrono>
volatile int sink;
int main()
{
std::cout << std::fixed << std::setprecision(9) << std::left;
for (auto size = 1ull; size < 1000'000'000ull; size *= 100) {
// record start time
auto start = std::chrono::system_clock::now();
// do some work
std::vector<int> v(size, 42);
sink = std::accumulate(v.begin(), v.end(), 0u); // make sure it's a side effect
// record end time
auto end = std::chrono::system_clock::now();
std::chrono::duration<double> diff = end-start;
std::cout << "Time to fill and iterate a vector of " << std::setw(9)
<< size << " ints : " << diff.count() << " s\n";
}
}
Is there any point of having end variable? Would
std::chrono::duration<double> diff = std::chrono::system_clock::now() - start;
produce exactly same result?

how to execute the running time of a program written in c++?

I have code that generates random numbers from 1-100 and sorts them using the merge sort which I already have in a separate function. Everything works but when I implement clock(); to try and get the running time, I always get zero. I have even tried with larger numbers like 10000 but still, the time passed always gives me zero. here is my code
int main() {
clock_t startTime;
clock_t endTime;
clock_t timePassed;
int array[100];
srand(time(NULL));
int n = sizeof(array) / sizeof(array[0]);
startTime = clock();
for (int j = 0; j < 100; j++)
{
array[j] = rand() % 100+1;
std::cout << array[j] << " ";
}
std::cout << "\n";
MergeSort(array, n);
std::cout << "After Merge Sort :" << std::endl;
PrintArray(array, n);
endTime = clock();
timePassed = ((endTime - startTime) / CLOCKS_PER_SEC);
std::cout << "\n" << timePassed;
}
return 0;
}
use
double timePassed = (endTime - startTime) / static_cast<double>(CLOCKS_PER_SEC);
Plan B for higher accuracy:
#include <iostream>
#include <chrono>
// ...
auto start_time{ std::chrono::high_resolution_clock::now() };
// ... code you want to time
auto end_time{ std::chrono::high_resolution_clock::now() };
std::cout << std::chrono::duration_cast<std::chrono::seconds>(end_time - start_time).count() << ":";
std::cout << std::chrono::duration_cast<std::chrono::microseconds>(end_time - start_time).count() << ":";
// ...
If you are developing on a Unix system and want to measure the execution time from an application, you can also use the 'time' command like:
time myapplication
see
time (Unix) - Wikipedia

C++ iterator in loop

+++ See update below +++
This is a code for reverse printing the content of an array. I used 3 slightly different methods for doing it: directly putting the dimension of the array in the for loop, using iterator and using reverse_iterator and measured the execution time of printing the for loop.
#include <iostream>
#include <vector>
#include <chrono>
using get_time = std::chrono::high_resolution_clock;
int main() {
std::cout << "Enter the array dimension:";
int N;
std::cin >> N;
//Read the array elements
std::cout << "Enter the array elements:" <<'\n';
std::vector <int> v;
int input;
for(size_t i=0; i<N; i++){
std::cin >> input;
v.push_back(input);
}
auto start = get_time::now();
for(int i=N-1; i>=0; i--){
std::cout << v[i] <<" ";
}
auto finish = get_time::now();
auto time_diff=finish-start;
std::cout << "Elapsed time,non-iterator= " << std::chrono::duration<double>
(time_diff).count() << " Seconds" << '\n';
auto start2 = get_time::now();
std::vector <int>::reverse_iterator ri;
for(ri=v.rbegin(); ri!=v.rend(); ri++){
std::cout << *ri <<" ";
}
auto finish2 = get_time::now();
auto time_diff2=finish2-start2;
std::cout << "Elapsed time, reverse iterator= " << std::chrono::duration<double>
(time_diff2).count() << " Seconds" << '\n';
auto start3 = get_time::now();
std::vector <int>::iterator i;
for(i=v.end()-1; i>=v.begin(); i--){
std::cout << *i <<" ";
}
auto finish3 = get_time::now();
auto time_diff3=finish3-start3;
std::cout << "Elapsed time, iterator= " << std::chrono::duration<double>
(time_diff3).count() << " Seconds" << '\n';
return 0;
}
The output is as follows:
Output:
5 4 3 2 1 Elapsed time,non-iterator= 2.7913e-05 Seconds
5 4 3 2 1 Elapsed time, reverse iterator= 5.57e-06 Seconds
5 4 3 2 1 Elapsed time, iterator= 4.56e-06 Seconds
My question is:
Why the direct method is almost 5 times slower than both iterator and reverse_iterator methods? Also, is this faster execution of iterator machine dependent?
This is a prototype, but I will need to deal with much bigger matrices; that is why I am asking this question. Thank you.
+++ Update +++
I am posting the updated results after incorporating the comments. It was too big for a comment.
I changed the for loop to evaluate the sum of an array with 100000 elements. I evaluated the same sum using the above mentioned methods (compiled with -O3 in clang++) and I have averaged the execution time for 3 methods over 10000 runs. Here are the results:
Average (10000 runs) elapsed time, non-iterator= 2.50183e-05
Average (10000 runs) elapsed time, reverse-iterator= 3.48299e-05
Average (10000 runs) elapsed time, iterator= 7.35307e-05
The results are much more uniform now, and now the non-iterator method is the fastest! Any insights? Or even this result is meaningless and I should do some more test?
the updated code:
#include <iostream>
#include <vector>
#include <chrono>
using get_time = std::chrono::high_resolution_clock;
int main() {
double time1,time2,time3;
int run=10000;
for(int k=0; k<run; k++){
//Read the array elements
std::vector <int> v;
int input,N=100000;
for(size_t i=0; i<N; i++){
v.push_back(i);
}
int sum1{0},sum2{0},sum3{0};
auto start = get_time::now();
for(int i=N-1; i>=0; i--){
sum1+=v[i];
}
auto finish = get_time::now();
auto time_diff=finish-start;
std::cout << "Sum= " << sum1 << " " << "Elapsed time,non-iterator= " << std::chrono::duration<double>
(time_diff).count() << " Seconds" << '\n';
auto start2 = get_time::now();
std::vector <int>::reverse_iterator ri;
for(ri=v.rbegin(); ri!=v.rend(); ri++){
sum2+=*ri;
}
auto finish2 = get_time::now();
auto time_diff2=finish2-start2;
std::cout << "Sum= " << sum2 <<" Elapsed time, reverse iterator= " << std::chrono::duration<double>
(time_diff2).count() << " Seconds" << '\n';
auto start3 = get_time::now();
std::vector <int>::iterator i;
for(i=v.end()-1; i>=v.begin(); i--){
sum3+=*i;
}
auto finish3 = get_time::now();
auto time_diff3=finish3-start3;
std::cout << "Sum= " <<sum3 << " Elapsed time, iterator= " << std::chrono::duration<double>
(time_diff3).count() << " Seconds" << '\n';
time1+=std::chrono::duration<double>(time_diff).count();
time2+=std::chrono::duration<double>(time_diff2).count();
time3+=std::chrono::duration<double>(time_diff3).count();
}
std::cout << "Average (" << run << " runs)" << " elapsed time, non-iterator= " << time1/double(run) <<'\n';
std::cout << "Average (" << run << " runs)" << " elapsed time, reverse-iterator= " << time2/double(run) <<'\n';
std::cout << "Average (" << run << " runs)" << " elapsed time, iterator= " << time3/double(run) <<'\n';
return 0;
}

system_clock returning negative time c++

I'm writing code to time a for loop, and I used code given to me by my professor, and it uses system_clock.
My problem is that on one of my for loops that I am timing, it is returning a negative time. Sometimes it's different number, but always negative.
Here's the code:
std::chrono::time_point<std::chrono::system_clock> start2, end2;
int sum2 = 0;
std::cout << "Sum on reference ";
start2 = std::chrono::system_clock::now();
for(int i = 0; i < 10000; i++)
{
sum2 = secondSum(dr);
}
end2 - std::chrono::system_clock::now();
std::chrono::duration<double> elapsed_seconds2 = end2 - start2;
std::cout << "sum: " << sum2 << std::endl;
std::cout << "Elapsed time for data processing on reference: " << elapsed_seconds2.count() << "s\n";
Where dr is a reference to a struct with a filled array inside and secondSum is a function that sums different values inside that array.
You need to change the line end2 - std::chrono::system_clock::now(); to end2 = std::chrono::system_clock::now();. After that your code should work exactly how you intended it to work.