C++ - ctime과 chrono
C++
C++ - ctime과 chrono
Chrono 공부
어제 정렬 알고리즘에 대해 공부하면서 사용했던, chrono에 대해 공부했다.
chrono
C 언어 때부터 사용된 ctime 라이브러리의 단점을 보완한 시간 처리 라이브러로, c++11 이후부터 사용되었다.
ctime과 chrono의 차이
시간 간격과 시점
두 라이브러리는 시간을 다루기 위한 개념이 다르다. ctime의 경우 시간을 숫자로 보며, 단일적인 개념으로 다룬다.
- 그와 반대로 chrono는 두 개의 개념으로 시간을 나누는데, 이것이 시간 간격과 시점이다.
- 시간 간격(duration)
- 두 시점 사이의 시간의 길이를 나타낸 단위 시점(time_point)
- 특정 시계를 기준으로 한 시점
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
void TimePointAndDuration()
{
//ctime은 시점과 시간 간격을 구분하지 않고 처리한다.
std::time_t t1 = std::time(nullptr); // 현 시점
std::time_t t2 = t1 + 10; //10초 후
double interval = std::difftime(t2, t1); //시간 간격 계산 (여기선 t1, t2가 시간 간격으로 해석된다)
cout << "10초 간격" << interval << "초" << endl;
//chrono에선 시간 간격과 시점의 개념을 분리해 따로 처리한다.
//chrono의 시간 간격
std::chrono::milliseconds ms(1000); // milliseconds는 std::chrono::duration 의 구현 클래스다.
cout << "총 합 : " << ms.count() << "밀리초" << endl;
//chrono의 시점
std::chrono::system_clock::time_point now = std::chrono::system_clock::now();
std::chrono::system_clock::time_point one_hour_later = now + std::chrono::hours(1);
std::chrono::system_clock::duration duration = one_hour_later - now; //시점끼리의 연산은 시간 간격으로 변환된다.
cout << "1시간 차이 : " << std::chrono::duration_cast<std::chrono::seconds>(duration).count() << " 초 " << endl;
}
정밀성
ctime의 경우 초 단위로만 시간 간격과 시점을 나타낸다. 밀리초, 나노초 같은 더 작은 단위를 처리하려면 os별 함수나 라이브러리를 따로 사용해야한다. 그러므로 정밀도를 요구하는 작업에 적합하지 않다. chrono는 millisecs, microsecs, secs, minutes, hours 같이 다양한 단위로 나타낼 수 있다.
1
2
3
4
5
6
7
8
9
10
11
12
void Precision()
{
//ctime은 초 단위로만 표현 가능하다.
std::time_t tSec = std::time(nullptr);
std::time_t tMilliSec = tSec * 1000;
std::time_t tMicroSec = tSec * 1000000;
// chrono는 다양한 단위로 나타내기 가능
std::chrono::system_clock::time_point cSec = std::chrono::system_clock::now();
std::chrono::system_clock::time_point cMilliSec = std::chrono::time_point_cast<std::chrono::milliseconds>(cSec);
std::chrono::system_clock::time_point cMicroSec = std::chrono::time_point_cast<std::chrono::microseconds>(cSec);
}
시계
ctime은 시스템 시계에만 의존한다. 시스템 시계는 사용가나 날짜/시간을 변경하면 영향을 받기에, 시간 간격 계산의 신뢰성이 떨어진다. chrono는 3 가지 타입의 시계가 있다. std::chrono::system_clock
- 시스템 시간
- ctime이 사용하는 시계다. std::chrono::steady_clock
- 시간의 흐름이 일정한 시계
- 프로그램 실행 시간 측정에 적합하다. std::chrono::hight_resolution_clock
- 가장 높은 정밀도를 제공한다.
- steady_clock이나 system_clock에 매핑된다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void Clocks()
{
//ctime의 시계
std::time_t cNow = std::time(nullptr); // 시스템 시계만 사용이 가능하다.
// chrono의 시계들
std::chrono::system_clock::time_point sysNow = std::chrono::system_clock::now(); // 현재 시스템 시간을 받아옴
std::chrono::system_clock::duration sysDuration = sysNow.time_since_epoch(); // Epoch 이후 초 단위 시간
std::chrono::steady_clock::time_point stNow = std::chrono::steady_clock::now(); // 시간의 흐름이 일정한 시계
std::chrono::steady_clock::duration stDuration = stNow.time_since_epoch(); // 성능 측정, 시간 간격 측정에 사용된다.
std::chrono::high_resolution_clock::time_point hrcNow = std::chrono::high_resolution_clock::now(); //가장 높은 정밀도를 제공
std::chrono::high_resolution_clock::duration hrcDuration = hrcNow.time_since_epoch(); //내부적인 구현은 steady_clock 또는 system_clock 중 하나에 매핑
}
연산
ctime의 time_t는 초 단위로 연산이 가능하며, 정수형과 유사하기에 기본적인 산술 연산을 사용 가능하다.
chrono의 경우 마치 물리학의 위치와 벡터와 비슷한 결과를 가진다고 생각한다. time_point를 위치, duartion을 벡터로 빗대어 본다면
- 두 위치간의 연산 중 뺄셈만 유일하게 의미를 가지는 것 처럼, time_point 끼리의 산술연산은 뺄셈만 가능하다.
- 위치와 벡터의 연산 중 덧셈, 뺄셈만 의미를 가지고, time_point와 duration의 연산도 덧셈, 뺄셈만 지원한다.
- 벡터끼리는 덧셈, 뺄셈이 가능하며, duration끼리의 연산도 그렇다.
- 위치와 스칼라 값이 직접적인 연산이 불가능하듯, time_point도 스칼라 값과 연산이 불가능하다.
- 벡터가 스칼라 값과 곱셈, 나눗셈 이 가능하듯, duration도 스칼라 값과 곱셈, 나눗셈이 가능하다.
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
void Operators()
{
std::time_t cTime = std::time(nullptr);
cout << "cTime :" << cTime << endl;
cout << "cTime + 10 : " << cTime + 10 << endl;
cout << "cTime - 10 : " << cTime - 10 << endl;
cout << "cTime * 10 : " << cTime * 10 << endl;
cout << "cTime / 10 : " << cTime / 10 << endl;
cout << "cTime % 10 : " << cTime % 10 << endl;
cout << "++cTime : " << ++cTime << endl;
cout << "--cTime : " << --cTime << endl;
std::chrono::system_clock::time_point now = std::chrono::system_clock::now();
std::chrono::system_clock::time_point one_hour_later = now + std::chrono::hours(1); // time_point와 duration의 연산 결과는 time_point
std::chrono::system_clock::duration duration = one_hour_later - now; // time_point 끼리의 연산은 duration
cout << "time_point 끼리의 연산 : " << duration.count() << endl;
cout << "time_point와 duration의 연산 : " << std::chrono::system_clock::to_time_t(one_hour_later) << endl;
std::chrono::system_clock::duration d1(5); // 5초
std::chrono::system_clock::duration d2(10); // 10초
auto sum = d1 + d2;
cout << "Sum: " << sum.count() << " seconds" << endl;
auto diff = d2 - d1;
cout << "Difference: " << diff.count() << " seconds" << endl;
auto mul = d1 * 2; // 5초 * 2 = 10초
cout << "Multiplication: " << mul.count() << " seconds" << endl;
auto div = d2 / 2; // 10초 / 2 = 5초
cout << "Division: " << div.count() << " seconds" << endl;
}
연산 결과
또 다른 chrono의 특징
- 일반적인 C++ 표준 라이브러리는 std 네임스페이스에 바로 정의되지만, Chrono는 예외적으로 std::chrono 아래에 있다.
- Chrono의 요소에는 시간 단위와 시계, 그리고 시간 연산에 사용되는 클래스가 포함된다.
- C++ 20 전에는 포멧을 지원하지 않았었다.
This post is licensed under CC BY 4.0 by the author.