Câu hỏi này đã có một câu trả lời tốt. Nhưng tôi muốn thêm đề xuất khác:
Làm việc trong khuôn khổ <chrono>
. Xây dựng đồng hồ của riêng bạn. Xây dựng time_point của riêng bạn. Xây dựng thời lượng của riêng bạn. Khung <chrono>
rất tùy chỉnh. Bằng cách làm việc trong hệ thống đó, bạn sẽ không chỉ tìm hiểu std::chrono
, nhưng khi nhà cung cấp của bạn bắt đầu vận chuyển đồng hồ bạn hài lòng, nó sẽ là tầm thường để chuyển mã của bạn từ chrono tay của bạn :: clock to std::high_resolution_clock
(hoặc bất kỳ).
Đầu tiên, mặc dù một lời chỉ trích nhỏ về mã ban đầu của bạn:
std::cout << "seconds since start: " << ((double) difference/1000000);
Bất cứ khi nào bạn thấy mình giới thiệu hằng số chuyển đổi (như 1000000) để có được những gì bạn muốn, bạn không sử dụng một cách chính xác chrono
. Mã của bạn không chính xác, chỉ mong manh. Bạn có phải là chắc chắn bạn có đúng số không trong hằng số đó không ?!
Ngay cả trong ví dụ đơn giản này, bạn nên nói với chính mình:
Tôi muốn nhìn thấy đầu ra về giây đại diện bởi một đôi.
Và sau đó bạn nên sử dụng chrono
làm điều đó cho bạn. Nó rất dễ dàng khi bạn tìm hiểu cách làm:
typedef std::chrono::duration<double> sec;
sec difference = end - start;
std::cout << "seconds since start: " << difference.count() << '\n';
Dòng đầu tiên tạo ra một loại với khoảng thời gian 1 giây, được biểu thị bằng một đôi.
Dòng thứ hai chỉ đơn giản là trừ các mốc thời gian của bạn và gán nó vào loại thời lượng tùy chỉnh của bạn. Việc chuyển đổi từ các đơn vị của steady_clock::time_point
sang thời lượng tùy chỉnh của bạn (một giây đôi) được thực hiện tự động bởi thư viện chrono
.Điều này đơn giản hơn nhiều:
auto difference = std::chrono::duration_cast<std::chrono::microseconds>(end - start).count()
Và cuối cùng bạn chỉ cần in kết quả của mình bằng hàm thành viên .count()
. Đây lại là đơn giản hơn nhiều so với:
std::cout << "seconds since start: " << ((double) difference/1000000);
Nhưng kể từ khi bạn không hài lòng với độ chính xác của std::chrono::steady_clock
, và bạn có quyền truy cập vào QueryPerformanceCounter, bạn có thể làm tốt hơn. Bạn có thể xây dựng đồng hồ của riêng mình trên đầu trang của QueryPerformanceCounter.
<disclaimer>
Tôi không có hệ thống Windows để kiểm tra mã sau.
</disclaimer>
struct my_clock
{
typedef double rep;
typedef std::ratio<1> period;
typedef std::chrono::duration<rep, period> duration;
typedef std::chrono::time_point<my_clock> time_point;
static const bool is_steady = false;
static time_point now()
{
static const long long frequency = init_frequency();
long long t;
QueryPerformanceCounter(&t);
return time_point(duration(static_cast<rep>(t)/frequency));
}
private:
static long long init_frequency()
{
long long f;
QueryPerformanceFrequency(&f);
return f;
}
};
Vì bạn muốn đầu ra của bạn trong điều kiện của một giây đôi, tôi đã thực hiện các rep
của đồng hồ này một double
và period
1 giây. Bạn có thể dễ dàng tạo ra tích phân rep
và period
một số đơn vị khác như micro giây hoặc nano giây. Bạn chỉ cần điều chỉnh typedef
s và chuyển đổi từ QueryPerformanceCounter
thành duration
trong now()
.
Và bây giờ mã của bạn có thể trông giống như mã ban đầu của bạn:
int main()
{
auto start = my_clock::now();
for (unsigned long long int i = 0; i < 10000; ++i) {
std::vector<int> v(i, 1);
}
auto end = my_clock::now();
auto difference = end - start;
std::cout << "seconds since start: " << difference.count() << '\n';
}
Nhưng mà không các hằng số chuyển đổi tay mã cố định và với (những gì tôi hy vọng là) đủ chính xác cho bạn nhu cầu. Và với đường dẫn port dễ dàng hơn để triển khai std::chrono::steady_clock
trong tương lai.
<chrono>
được thiết kế để trở thành thư viện có thể mở rộng. Vui lòng mở rộng. :-)
Thay vào đó hãy thử 'std :: chrono :: high_resolution_clock'. –
@KerrekSB: Đó là một gợi ý tốt, nhưng 'steady_clock :: now()' nên đã chính xác đến nano giây, hoặc ít nhất là ve (khoảng 100 nano giây). Tôi nghi ngờ có một vấn đề toán học ở đây. –
@RobertHarvey: Ồ, có lẽ các dấu ngoặc đơn bị thất lạc trong dàn diễn viên? –