Is there an easy way to get the time elapsed during std::future<T>::wait_for if no time-out occurred? I want to achieves something like this:
std::future<void> futureRet = std::async(std::launch::async, &Someone::doSomething, this);
futureRet.wait_for(std::chrono::seconds(30));
cout << "doSomething returned after <" << futureRet.getElapsedTime() << "> seconds.";
Is there a kind of "getElapsedTime()" function or do I have to calculate the elapsed time myself?
There is an easy way using <chrono>:
auto start = std::chrono::steady_clock::now();
std::future<void> futureRet = std::async(std::launch::async, &Someone::doSomething, this);
futureRet.wait_for(std::chrono::seconds(30));
auto end = std::chrono::steady_clock::now();
std::chrono::duration<double> elapsed_seconds = end - start;
cout << "doSomething returned after <" << elapsed_seconds.count() << "> seconds.";
Related
I want to list all the files on a computer. Even on multiple drives, if the computer has multiple drives. Cloud does not have to be included, just the local files.
I have tried recursive_directory_iterator from <filesystem> (C++17). But that code is SO slow. Maybe it's not written optimally. So can someone help me on how to do this relatively quickly. It has to be able to store the file path in a string one at a time so the program can work with the file and when it's finished with that file, the next overwrites the string. It doesn't have to display the path like in the example provided, but it's good if it can.
The code:
for (auto& p : std::filesystem::recursive_directory_iterator("C:\\")) {
std::cout << p.path() << '\n';
}
When I ran this, it worked. I have around 450GB of data on my C: drive and lots of folders, and in around 8 minutes it still was 1/3 done or probably less. The program has to be run as an administrator unless it will trip up at certain folders/files. But that's not a problem.
Depending on your environment, the thing that is mainly slowing down the example you posted is writing the path to the console, assuming that you did not redirect std::cout to write somewhere else.
A couple of benchmarks I tested with a directory that contains 2902 files:
Default behaviour of std::cout writing to the console: 13253.1ms
auto t1 = std::chrono::high_resolution_clock::now();
for (auto& p : std::filesystem::recursive_directory_iterator("C:\\")) {
std::cout << p.path() << '\n';
}
auto t2 = std::chrono::high_resolution_clock::now();
std::chrono::duration<double, std::milli> ms_double = t2 - t1;
std::cout << ms_double.count() << "ms";
Redirecting std::cout to write to a file (out.txt): 34.0928ms
std::ofstream out("D:\\out.txt");
std::streambuf* coutbuf = std::cout.rdbuf(); //save old buf
std::cout.rdbuf(out.rdbuf()); //redirect std::cout to out.txt
auto t1 = std::chrono::high_resolution_clock::now();
for (auto& p : std::filesystem::recursive_directory_iterator("C:\\")) {
std::cout << p.path() << '\n';
}
auto t2 = std::chrono::high_resolution_clock::now();
std::chrono::duration<double, std::milli> ms_double = t2 - t1;
std::cout << ms_double.count() << "ms";
Not using std::cout at all: 32.2823ms
auto t1 = std::chrono::high_resolution_clock::now();
for (auto& p : std::filesystem::recursive_directory_iterator("C:\\")) {
}
auto t2 = std::chrono::high_resolution_clock::now();
std::chrono::duration<double, std::milli> ms_double = t2 - t1;
std::cout << ms_double.count() << "ms";
I'm writing a class as follows:
struct TimeIt {
using TimePoint = std::chrono::time_point<std::chrono::high_resolution_clock>;
TimeIt(const std::string& functName) :
t1{std::chrono::high_resolution_clock::now()},
functName{functName} {}
~TimeIt() {
TimePoint t2 = std::chrono::high_resolution_clock::now();
std::cout << "Exiting from " << functName << "...\n Elapsed: ";
std::cout << std::chrono::duration_cast<std::chrono::milliseconds>(t2 - t1).count() << " ms" << "\n";
}
TimePoint t1;
std::string functName;
};
The whole point of it is measure the time that takes for one function to complete, calling this at the start of it. However, the only value I'm getting is 0ms. This is obviously wrong, because it takes up to a minute for some of the functions, but I can't see why it's wrong.
I did the same, but at the start and end of the function, creating the TimePoint (with auto) and doing a duration_cast. Any clue what I'm missing here?
Edit:
I'm going to try to make it reproducible. A little bit of context: I'm working with big matrixes (12000 dimensions) and doing a lot of input output operations.
template <typename InputType>
InputMat<InputType>
readInp(const std::string& filepath = "data.inp", const size_t& reserveSize = 15000) {
TimeIt("readInp");
std::ifstream F(filepath);
assert(F.is_open());
InputMat<InputType> res;
res.reserve(reserveSize);
std::string line;
while (F >> line) {
InputType lineBitset{line};
res.push_back(lineBitset);
}
return res;
}
This function reads a matrix, and calling TimeIt here gives really different results compared when I call it in the wrapper function:
void test1() {
//Testing for 0-1 values
auto t1 = std::chrono::high_resolution_clock::now();
auto inpMat = readInp<std::bitset<32>>();
auto t2 = std::chrono::high_resolution_clock::now();
std::cout << std::chrono::duration_cast<std::chrono::milliseconds>(t2 - t1).count() << "\n";
//More code...
}
This outputs:
Exiting from readInp...
Elapsed: 0 milliseconds
4
and data.inp
NOW you have made the problem clear! By writing this:
TimeIt("Reading");
you are creating a temporary object, which is immediately deleted. You need to give this object a name so it lives until the end of the block:
TimeIt timer("Reading");
I try to get the time elapsed between two points in time in milliseconds as integer or in seconds as double.
I'm trying to put constant acceleration of 4m/s² on something. I got this already:
int main() {
double accel = 4, velocity = 0;
auto start = chrono::system_clock::now();
sleep(3);
auto ende = chrono::system_clock::now();
chrono::duration<double> elapsed_seconds = ende - start;
velocity += accel * elapsed_seconds; //This is where I don't know what to put instead of "elapsed_seconds"
cout << "Velocity after " << elapsed_seconds << "s is " << velocity << "m/s" << endl;
return 0;
}
But as you might see it doesn't work. I already found something like
chrono::duration_cast<ms>(elapsed_time);
but I can't get it to work. Do you have any ideas?
It's maybe a little strange to say you "count" a double but elapsed_seconds.count() will return the underlying value.
To get the seconds as a double:
auto seconds = chrono::duration<double>(ende - start);
auto val = seconds.count();
To get milliseconds:
auto ms = chrono::duration_cast<chrono::milliseconds>(ende - start);
auto val = ms.count();
Be careful when using duration_cast, you can lose precision.
While I realize this is probably one of many identical questions, I can't seem to figure out how to properly use std::chrono. This is the solution I cobbled together.
#include <stdlib.h>
#include <iostream>
#include <chrono>
typedef std::chrono::high_resolution_clock Time;
typedef std::chrono::milliseconds ms;
float startTime;
float getCurrentTime();
int main () {
startTime = getCurrentTime();
std::cout << "Start Time: " << startTime << "\n";
while(true) {
std::cout << getCurrentTime() - startTime << "\n";
}
return EXIT_SUCCESS;
}
float getCurrentTime() {
auto now = Time::now();
return std::chrono::duration_cast<ms>(now.time_since_epoch()).count() / 1000;
}
For some reason, this only ever returns integer values as the difference, which increments upwards at rate of 1 per second, but starting from an arbitrary, often negative, value.
What am I doing wrong? Is there a better way of doing this?
Don't escape the chrono type system until you absolutely have to. That means don't use .count() except for I/O or interacting with legacy API.
This translates to: Don't use float as time_point.
Don't bother with high_resolution_clock. This is always a typedef to either system_clock or steady_clock. For more portable code, choose one of the latter.
.
#include <iostream>
#include <chrono>
using Time = std::chrono::steady_clock;
using ms = std::chrono::milliseconds;
To start, you're going to need a duration with a representation of float and the units of seconds. This is how you do that:
using float_sec = std::chrono::duration<float>;
Next you need a time_point which uses Time as the clock, and float_sec as its duration:
using float_time_point = std::chrono::time_point<Time, float_sec>;
Now your getCurrentTime() can just return Time::now(). No fuss, no muss:
float_time_point
getCurrentTime() {
return Time::now();
}
Your main, because it has to do the I/O, is responsible for unpacking the chrono types into scalars so that it can print them:
int main () {
auto startTime = getCurrentTime();
std::cout << "Start Time: " << startTime.time_since_epoch().count() << "\n";
while(true) {
std::cout << (getCurrentTime() - startTime).count() << "\n";
}
}
This program does a similar thing. Hopefully it shows some of the capabilities (and methodology) of std::chrono:
#include <iostream>
#include <chrono>
#include <thread>
int main()
{
using namespace std::literals;
namespace chrono = std::chrono;
using clock_type = chrono::high_resolution_clock;
auto start = clock_type::now();
for(;;) {
auto first = clock_type::now();
// note use of literal - this is c++14
std::this_thread::sleep_for(500ms);
// c++11 would be this:
// std::this_thread::sleep_for(chrono::milliseconds(500));
auto last = clock_type::now();
auto interval = last - first;
auto total = last - start;
// integer cast
std::cout << "we just slept for " << chrono::duration_cast<chrono::milliseconds>(interval).count() << "ms\n";
// another integer cast
std::cout << "also known as " << chrono::duration_cast<chrono::nanoseconds>(interval).count() << "ns\n";
// floating point cast
using seconds_fp = chrono::duration<double, chrono::seconds::period>;
std::cout << "which is " << chrono::duration_cast<seconds_fp>(interval).count() << " seconds\n";
std::cout << " total time wasted: " << chrono::duration_cast<chrono::milliseconds>(total).count() << "ms\n";
std::cout << " in seconds: " << chrono::duration_cast<seconds_fp>(total).count() << "s\n";
std::cout << std::endl;
}
return 0;
}
example output:
we just slept for 503ms
also known as 503144616ns
which is 0.503145 seconds
total time wasted: 503ms
in seconds: 0.503145s
we just slept for 500ms
also known as 500799185ns
which is 0.500799 seconds
total time wasted: 1004ms
in seconds: 1.00405s
we just slept for 505ms
also known as 505114589ns
which is 0.505115 seconds
total time wasted: 1509ms
in seconds: 1.50923s
we just slept for 502ms
also known as 502478275ns
which is 0.502478 seconds
total time wasted: 2011ms
in seconds: 2.01183s
I am using boost::posix_time::ptime to measure my simulation run-time and for something else.
assuimg
boost::posix_time::ptime start, stop;
boost::posix_time::time_duration diff;
start = boost::posix_time::microsec_clock::local_time();
sleep(5);
stop = boost::posix_time::microsec_clock::local_time();
diff = stop - stop;
now
std::cout << to_simple_string( diff ) << std::endl;
return the time in hh:mm:ss.ssssss format and i would like to have the time as well in ss.sssssss.
for doing this, i tried
boost::posix_time::time_duration::sec_type x = diff.total_seconds();
but that gave me the answer in format of ss and seconds() returns Returns normalized number of seconds (0..60).
My question how could i get my simulation time in seconds of the format ss.ssssss?
EDIT
i was able to do:
std::cout << diff.total_seconds() << "." << diff.fractional_seconds() << std::endl;
is there something elegant that could plot ss.sssssss?
total_seconds() returns a long value which is not normalized to 0..60s.
So just do this:
namespace bpt = boost::posix_time;
int main(int , char** )
{
bpt::ptime start, stop;
start = bpt::microsec_clock::local_time();
sleep(62);
stop = bpt::microsec_clock::local_time();
bpt::time_duration dur = stop - start;
long milliseconds = dur.total_milliseconds();
std::cout << milliseconds << std::endl; // 62000
// format output with boost::format
boost::format output("%.2f");
output % (milliseconds/1000.0);
std::cout << output << std::endl; // 62.00
}
// whatever time you have (here 1second)
boost::posix_time::ptime pt = boost::posix_time::from_time_t( 1 );
// subtract 0 == cast to duration
boost::posix_time::time_duration dur = pt - boost::posix_time::from_time_t(0);
// result in ms
uint64_t ms = dur.total_milliseconds();
// result in usec
uint64_t us = dur.total_microseconds();
// result in sec
uint64_t s = dur.total_seconds();
std::cout << "s = " << s << ", ms = " << ms << ", us = " << us << std::endl;
s = 1, ms = 1000, us = 1000000
The most straight-forward way I see is something like this output, the rest of the time computations along the lines of nabulke's post:
#include <iomanip>
double dseconds = dur.total_milliseconds() / 1000. ;
std::cout << std::setiosflags(std::ios::fixed) << std::setprecision(3);
std::cout << dseconds << std::endl;
You want to express time in terms of a floating point number, so it's probably best to actually use one and apply the standard stream formatting manipulators.