개요
오늘 올라온 질문 포스트 중 DateTime.Now
와 DateTime.UtcNow
의 성능에 대한 내용이 있었어서 간단히 정리해보았습니다.
DateTime.Now vs DateTime.UtcNow.ToLocalTime
저 역시 DateTime.Now
가 DateTime.UtcNow
보다 느리다는 것을 알고 있었기에, 실무에서는 이를 개선하기 위한 캐싱 유틸리티를 만들어 사용한 경험이 있는데요, 닷넷 런타임이 업데이트 되면서 이러한 부분에 대한 성능 개선이 이루어 졌을 것으로 보고 이참에 벤치마크를 진행해봤습니다.
벤치마크 결과
※ Cached의 경우 연산 자체를 스킵하는 것이므로 소요된 절대 시간 값은 크게 의미 없습니다.
Method | .NET Core 3.1 | .NET FX 4.8 | .NET 6.0 | .NET 8.0 |
---|---|---|---|---|
UTCNow | 52.59 | 40.96 | 20.42 | 19.99 |
Now | 65.77 | 55.54 | 29.30 | 25.29 |
UTCNowToLocal | 66.16 | 53.85 | 31.37 | 26.45 |
UTCNowAddOffset | 54.68 | 42.27 | 21.43 | 21.40 |
CachedNow | 2.45 | 2.56 | 2.53 | 2.08 |
벤치마크 코드는 다음과 같습니다.
public class BenchmarkDateTime
{
[Benchmark()]
public DateTime UTCNow() => DateTime.UtcNow;
[Benchmark()]
public DateTime Now() => DateTime.Now;
[Benchmark()]
public DateTime UTCNowToLocal() => DateTime.UtcNow.ToLocalTime();
private TimeSpan _offset = TimeZoneInfo.Local.BaseUtcOffset;
[Benchmark()]
public DateTime UTCNowAddOffset()
=> DateTime.SpecifyKind(DateTime.UtcNow + _offset, DateTimeKind.Local);
private int _lastTickCount = -1;
private DateTime _lastDateTime;
[Benchmark()]
public DateTime CachedNow()
{
if (_lastTickCount != Environment.TickCount)
{
if (_lastTickCount != Environment.TickCount) // 동기화 대신 더블체크로 업데이트 횟수 감소
{
_lastTickCount = Environment.TickCount;
_lastDateTime = DateTime.SpecifyKind(DateTime.UtcNow + _offset, DateTimeKind.Local);
}
}
return _lastDateTime;
}
}
대용량 측정 데이터를 CPU Full Load로 처리 하는 로직에서 처리 시간 저장을 위해 DateTime.Now
를 초당 수십~수백만 번 호출했을 때 몇십 ms의 차이가 발생했던 기억이 있는데 최신 .NET Runtime에서는 기본적으로 성능 개선이 많이 이루어져서 차이가 크지 않은 것으로 보입니다.
1초에 수십 번 호출되는 경우 몇십 ns의 차이가 큰 의미가 없다면 DateTime.Now
를 그대로 사용하셔도 무방할 듯합니다.
DateTime.Now
캐싱
CachedNow
케이스의 경우 애초에 DateTime.Now
함수의 정확도가 수 ms 수준으로 정확하지 않다는 점에 착안해서 호출하는데 CPU를 거의 사용하지 않는 Environment.TickCount
속성을 기준으로 DateTime.Now
값을 캐싱하는 함수입니다.
자세한 내용은 아래 링크에서 참고하실 수 있습니다.
이 방법은 벌크 데이터 프로세싱과 같은 시나리오에서 10ms 내에 DateTime.Now
를 반복적으로 가져와야 하는 상황에서 적합합니다.
필요에 따라 적절히 활용해 보시면 좋겠습니다.
마치며
DateTime.Now
와 DateTime.UtcNow
의 성능 차이는 닷넷 버전에 따라 다소 달라지지만, 최신 환경에서는 실질적인 차이가 크지 않다는 점을 확인할 수 있었습니다. 성능에 큰 영향이 없는 경우라면 단순히 DateTime.Now
를 사용하는 것도 좋은 선택입니다. 상황에 따라 정밀도가 중요하지 않다면 캐싱을 고려할 수 있습니다.
이상으로 글을 마치며 DateTime
성능 최적화에 참고가 되길 바랍니다.