ã¯ããã«
éåžžã«å€ãã®å Žåãéçºè
ã¯ïŒèªåã®ã³ãŒãã ãã§ãªãïŒèªåã®ã³ãŒãã®å®è¡æéã枬å®ããå¿
èŠããããŸãã ããã°ã©ãã³ã°ãå§ããã°ããã®ãšãããããã®ç®çã§
DateTimeæ§é ã䜿çšããŸããã æéãçµã¡ã
ã¹ããããŠã©ããã¯ã©ã¹ã«ã€ããŠåŠã³ãç©æ¥µçã«äœ¿çšãå§ããŸããã åæ§ã®ç¶æ³ãããªãã«ããã£ããšæããŸãã ã¹ããããŠã©ãããã©ã®ããã«æ©èœããããèªåããªãã£ãããã§ã¯ãããŸãããããã®æç¹ã§ãDateTimeã§ååã ã£ãæéãããæ£ç¢ºã«è²»ãããæéã枬å®ã§ããããšãããããŸããã èªè
ã ãã§ãªããStopwatchã¯ã©ã¹ãå®éã«ã©ã®ããã«æ©èœããããèªåèªèº«ã§èª¬æããDateTimeã䜿çšããå Žåãšæ¯ã¹ãŠãã®é·æãšçæãèŠã€ããæãæ¥ãŸããã
DateTimeã䜿çšãã
DateTimeæ§é ã䜿çšããŠã³ãŒãã®å®è¡æéã枬å®ããã®ã¯éåžžã«ç°¡åã§ãã
var before = DateTime.Now; SomeOperation(); var spendTime = DateTime.Now - before;
ããããã£DateTime.Now-ããŒã«ã«ã®çŸåšã®æ¥ä»ãšæå»ãè¿ããŸãã DateTime.Nowããããã£ã®ä»£ããã«ãDateTime.UtcNowããããã£ã䜿çšã§ããŸããããã¯çŸåšã®æ¥ä»ãšæå»ãè¿ããŸãããããŒã«ã«ã¿ã€ã ãŸãŒã³ã§ã¯ãªããUtcæéãã€ãŸãäžçåå®æå»ãšããŠè¡šããŸãã
var before = DateTime.UtcNow; SomeOperation(); var spendTime = DateTime.UtcNow - before;
DateTimeã®æ§é ã«é¢ããããã€ãã®èšè
ãããããDateTimeæ§é ã®ãã¹ãŠã«ã€ããŠèããŠãã人ã¯ã»ãšãã©ããŸããã DateTimeæ§é äœã®å€ã¯ãã¡ãžã£ãŒãšåŒã°ãã100ããç§åäœã§æž¬å®ãããæ£ç¢ºãªæ¥ä»ã¯ã西æŠ0001幎1æ1æ¥00:00以éã«æž¡ãããã¡ãžã£ãŒã®æ°ã§è¡šãããŸãã
ããšãã°ãæ°å€628539264000000000ã¯ã1992幎10æ6æ¥00:00:00ãè¡šããŸãã
DateTimeæ§é ã«ã¯ãéå»ã®ã¡ãžã£ãŒã®æ°ãå«ãåäžã®ãã£ãŒã«ããå«ãŸããŸãã
private UInt64 dateData;
.NET 2.0以éããã®ãã£ãŒã«ãã®æäžäœ2ãããã¯DateTimeã¿ã€ãã瀺ããŸãïŒæå®ãªã-æå®ãªããUtc-調æŽæéãããŒã«ã«-ããŒã«ã«æéãããã³æ®ãã®62ããã-ãã£ãã¯æ°ã Kindããããã£ã䜿çšããŠããããã®2ããããç°¡åã«èŠæ±ã§ããŸãã
DateTimeã䜿çšããã®ã¯äœãæªãã§ããïŒ
DateTime.Nowããããã£ã䜿çšããŠæéééã枬å®ããããšã¯ãå§ãã§ããŸããããã®çç±ã¯æ¬¡ã®ãšããã§ãã
DateTime.Now public static DateTime Now { get { DateTime utc = DateTime.UtcNow; Boolean isAmbiguousLocalDst = false; Int64 offset = TimeZoneInfo.GetDateTimeNowUtcOffsetFromUtc(utc, out isAmbiguousLocalDst).Ticks; long tick = utc.Ticks + offset; if (tick > DateTime.MaxTicks) { return new DateTime(DateTime.MaxTicks, DateTimeKind.Local); } if (tick < DateTime.MinTicks) { return new DateTime(DateTime.MinTicks, DateTimeKind.Local); } return new DateTime(tick, DateTimeKind.Local, isAmbiguousLocalDst); } }
DateTime.Nowããããã£ã®èšç®ã¯DateTime.UtcNowã«åºã¥ããŠããŸããã€ãŸããæåã«èª¿æŽãããæéãèšç®ããã次ã«ã¿ã€ã ãŸãŒã³ãªãã»ãããé©çšãããŸãã
ãã®ãããDateTime.UtcNowããããã£ã䜿çšããæ¹ãããæ£ç¢ºã«ãªããŸããããã¯ã¯ããã«é«éã«èšç®ãããŸãã
DateTime.UtcNow public static DateTime UtcNow { get { long ticks = 0; ticks = GetSystemTimeAsFileTime(); return new DateTime(((UInt64)(ticks + FileTimeOffset)) | KindUtc); } }
DateTime.NowãŸãã¯DateTime.UtcNowã®äœ¿çšã«é¢ããåé¡ã¯ããããã®ç²ŸåºŠãä¿®æ£ãããŠããããšã§ãã äžèšã®ããã«
1ãã£ãã¯= 100ããç§= 0.1ãã€ã¯ãç§= 0.0001ããªç§= 0.0000001ç§ãããã£ãŠãé·ãã1å°ç¯ã®é·ãããçãæéééã枬å®ããããšã¯ãåã«äžå¯èœã§ãã ãã¡ãããå¿
èŠã«ãªãããšã¯ãŸããããŸãããããããç¥ãå¿
èŠããããŸãã
ã¹ããããŠã©ããã¯ã©ã¹ã®äœ¿çš
Stopwatchã¯ã©ã¹ã¯.NET 2.0ã«ç»å Žãããã以éã¯å€æŽãããŠããŸããã è²»ããããæéãæ£ç¢ºã«æž¬å®ããããã«äœ¿çšã§ããäžé£ã®æ¹æ³ãšããŒã«ãæäŸããŸãã
Stopwatchã¯ã©ã¹ã®ãããªãã¯APIã¯æ¬¡ã®ãšããã§ãã
ããããã£- çµé-åèšçµéæéãè¿ããŸãã
- ElapsedMilliseconds-åèšçµéæéãããªç§ã§è¿ããŸãã
- ElapsedTicks-åèšçµéæéãã¿ã€ããŒãã£ãã¯ã§è¿ããŸãã
- IsRunning-ã¹ããããŠã©ããã¿ã€ããŒãå®è¡äžãã©ããã瀺ãå€ãè¿ããŸãã
æ¹æ³- ãªã»ãã-æéééã®æž¬å®ãåæ¢ããçµéæéããªã»ããããŸãã
- åèµ·å-æéééã®æž¬å®ãåæ¢ããçµéæéããªã»ããããçµéæéã®æž¬å®ãéå§ããŸãã
- éå§-ã€ã³ã¿ãŒãã«ã®çµéæéã®æž¬å®ãéå§ãŸãã¯ç¶ç¶ããŸãã
- StartNew-ã¹ããããŠã©ããã®æ°ããã€ã³ã¹ã¿ã³ã¹ãåæåããçµéæéããããã£ããŒãã«èšå®ããŠãçµéæéã®æž¬å®ãéå§ããŸãã
- åæ¢-ã€ã³ã¿ãŒãã«ã®çµéæéã®æž¬å®ãåæ¢ããŸãã
ãã£ãŒã«ã- é »åºŠ-ã¿ã€ããŒã®é »åºŠã1ç§ãããã®ã¡ãžã£ãŒæ°ãšããŠè¿ããŸãã
- IsHighResolution-ã¿ã€ããŒãé«è§£å床ããã©ãŒãã³ã¹ã«ãŠã³ã¿ãŒã«äŸåãããã©ããã瀺ããŸãã
StopWatchã¯ã©ã¹ã䜿çšããŠSomeOperationã¡ãœããã®å®è¡æéã枬å®ããã³ãŒãã¯æ¬¡ã®ããã«ãªããŸãã
var sw = new Stopwatch(); sw.Start(); SomeOperation(); sw.Stop();
æåã®2è¡ã¯ãããç°¡æœã«èšè¿°ã§ããŸãã
var sw = Stopwatch.StartNew(); SomeOperation(); sw.Stop();
ã¹ããããŠã©ããã®å®è£
Stopwatchã¯ã©ã¹ã¯HPETïŒé«ç²ŸåºŠã€ãã³ãã¿ã€ããŒïŒã«åºã¥ããŠããŸãã ãã®ã¿ã€ããŒã¯ãæé枬å®ã®åé¡ã«çµæ¢ç¬Šãæã€ããã«Microsoftã«ãã£ãŠå°å
¥ãããŸããã ãã®ã¿ã€ããŒã®åšæ³¢æ°ïŒæäœ10 MHzïŒã¯ãã·ã¹ãã ã®åäœäžã«å€åããŸããã ã·ã¹ãã ããšã«ãWindowsèªäœããã®ã¿ã€ããŒãå®è£
ããããã€ã¹ã決å®ããŸãã
Stopwatchã¯ã©ã¹ã«ã¯æ¬¡ã®ãã£ãŒã«ããå«ãŸããŸãã
private const long TicksPerMillisecond = 10000; private const long TicksPerSecond = TicksPerMillisecond * 1000; private bool isRunning; private long startTimeStamp; private long elapsed; private static readonly double tickFrequency;
TicksPerMillisecond-DateTimeã¡ãžã£ãŒã®æ°ã1ããªç§ã§æ±ºå®ããŸãã
TicksPerSecond-1ç§ã®DateTimeã¡ãžã£ãŒã®æ°ã決å®ããŸãã
isRunning-çŸåšã®ã€ã³ã¹ã¿ã³ã¹ãå®è¡äžãã©ããïŒStartã¡ãœãããåŒã³åºããããã©ããïŒã決å®ããŸãã
startTimeStamp-èµ·åæã®ã¡ãžã£ãŒã®æ°ã
çµé-è²»ããããã¡ãžã£ãŒã®ç·æ°ã
tickFrequency-ã¹ããããŠã©ããã®ã¡ãžã£ãŒãDateTimeã«ç°¡åã«å€æã§ããŸãã
éçã³ã³ã¹ãã©ã¯ã¿ãŒã¯HPETã¿ã€ããŒã®ååšããã§ãã¯ããååšããªãå Žåãã¹ããããŠã©ããã®é »åºŠã¯DateTimeã®é »åºŠã«èšå®ãããŸãã
éçã³ã³ã¹ãã©ã¯ã¿ãŒã®ã¹ããããŠã©ãã static Stopwatch() { bool succeeded = SafeNativeMethods.QueryPerformanceFrequency(out Frequency); if(!succeeded) { IsHighResolution = false; Frequency = TicksPerSecond; tickFrequency = 1; } else { IsHighResolution = true; tickFrequency = TicksPerSecond; tickFrequency /= Frequency; } }
ãã®ã¯ã©ã¹ã®äž»ãªã·ããªãªãäžã«ç€ºããŸããïŒæéã枬å®ããå¿
èŠãããStartã¡ãœãããžã®åŒã³åºãããããŠStopã¡ãœãããžã®åŒã³åºãã
Startã¡ãœããã®å®è£
ã¯éåžžã«ç°¡åã§ã-æåã®ã¡ãžã£ãŒæ°ãèšæ¶ããŸãïŒ
éå§ãã public void Start() { if (!isRunning) { startTimeStamp = GetTimestamp(); isRunning = true; } }
æ¢ã«æž¬å®äžã®ã€ã³ã¹ã¿ã³ã¹ã§Startã¡ãœãããåŒã³åºããŠãäœãèµ·ãããªãããšã«æ³šæããŠãã ãããStopã¡ãœããã¯ç°¡åã§ãã
ãã㊠public void Stop() { if (isRunning) { long endTimeStamp = GetTimestamp(); long elapsedThisPeriod = endTimeStamp - startTimeStamp; elapsed += elapsedThisPeriod; isRunning = false; if (elapsed < 0) {
åæ¢ããã€ã³ã¹ã¿ã³ã¹ã§Stopã¡ãœãããåŒã³åºãããšã倱æããŸããã©ã¡ãã®ã¡ãœãããGetTimestampïŒïŒåŒã³åºãã䜿çšããŸããããã¯ãåŒã³åºãæã«ã¡ãžã£ãŒã®æ°ãè¿ããŸãã
Gettimestamp public static long GetTimestamp() { if (IsHighResolution) { long timestamp = 0; SafeNativeMethods.QueryPerformanceCounter(out timestamp); return timestamp; } else { return DateTime.UtcNow.Ticks; } }
HPETïŒé«ç²ŸåºŠã€ãã³ãã¿ã€ããŒïŒã§ã¯ãã¹ããããŠã©ããã®æž¬å®å€ã¯DateTimeãšã¯ç°ãªããŸãã
次ã®ã³ãŒã
Console.WriteLine(Stopwatch.GetTimestamp()); Console.WriteLine(DateTime.UtcNow.Ticks);
ç§ã®ã³ã³ãã¥ãŒã¿ãŒã®ãã£ã¹ãã¬ã€ã«
5201678165559 635382513439102209
ã¹ããããŠã©ããã®ãã£ãã¯ã䜿çšããŠDateTimeãŸãã¯TimeSpanãäœæããã®ã¯ééã£ãŠããŸãã èšé²
var time = new TimeSpan(sw.ElaspedTicks);
æãããªçç±ã«ããã誀ã£ãçµæã«ã€ãªãããŸãã
ã¹ããããŠã©ããã§ã¯ãªãDateTimeã¡ãžã£ãŒãååŸããã«ã¯ãElapsedããã³ElapsedMillisecondsããããã£ã䜿çšããããæåã§å€æããå¿
èŠããããŸãã Stopwatchã¡ãžã£ãŒãDateTimeã¡ãžã£ãŒã«å€æããã«ã¯ãã¯ã©ã¹ã§æ¬¡ã®ã¡ãœããã䜿çšããŸãã
GetElapsedDateTimeTicks private long GetElapsedDateTimeTicks() { long rawTicks = GetRawElapsedTicks();
ããããã£ã³ãŒãã¯äºæ³ã©ããã«èŠããŸãã
çµéãçµéããªç§ public TimeSpan Elapsed { get { return new TimeSpan(GetElapsedDateTimeTicks()); } } public long ElapsedMilliseconds { get { return GetElapsedDateTimeTicks() / TicksPerMillisecond; } }
ã¹ããããŠã©ããã®äœ¿çšã®äœãæªãã®ã§ããïŒ
MSDNã§ã®ãã®ã¯ã©ã¹ãžã®æ³šæïŒãã«ãããã»ããµã³ã³ãã¥ãŒã¿ãŒã§ã¯ãã©ã®ããã»ããµãŒãã¹ã¬ãããå®è¡ããŠãããã¯é¢ä¿ãããŸããã ãã ããBIOSãŸãã¯æœè±¡æ©åšå±€ïŒHALïŒã®ãšã©ãŒã«ãããç°ãªãããã»ããµã§æéãèšç®ããçµæãç°ãªãå ŽåããããŸãã
ãããé¿ããããã«ãStopã¡ãœããã«ã¯ifïŒelapsed <0ïŒæ¡ä»¶ããããŸãã
HPETã®äžé©åãªæäœã®ããã«
èè
ãåé¡ã«ééãã
èšäºãããããèŠã€ããŸããã
HPETããªãå Žåãã¹ããããŠã©ããã¯DateTimeã¯ããã¯ã䜿çšãããããDateTimeã®æ瀺çãªäœ¿çšã«å¯Ÿããå©ç¹ã¯å€±ãããŸãã ããã«ãç¹ã«ã«ãŒãã§çºçããå Žåã¯ãStopwatchãè¡ãã¡ãœããåŒã³åºããšãã§ãã¯ã«è²»ãããæéãèæ
®ããå¿
èŠããããŸãã
ã¢ãã®ã¹ããããŠã©ãã
HPETãæäœããããã«ãã€ãã£ãã®Windowsé¢æ°ã«äŸåããå¿
èŠããªããããStopwatchã¯ã©ã¹ãã¢ãã©ã«ã§ã©ã®ããã«å®è£
ãããã®ãçåã«æã£ãŠããŸããã
public static readonly long Frequency = 10000000; public static readonly bool IsHighResolution = true;
ã¢ãã®ã¹ããããŠã©ããã¯åžžã«DateTimeã¯ããã¯ã䜿çšãããããã³ãŒããèªã¿ãããå Žåãé€ããDateTimeã®æ瀺çãªäœ¿çšã«åãå©ç¹ã¯ãããŸããã
Environment.TickCount
ãŸããEnvironment.TickCountããããã£ã«ã€ããŠã説æããå¿
èŠããããŸãããã®ããããã£ã¯ãã·ã¹ãã ãèµ·åããŠããçµéããæéïŒããªç§åäœïŒãè¿ããŸãã
ãã®ããããã£ã®å€ã¯ã·ã¹ãã ã¿ã€ããŒããååŸããã笊å·ä»ã32ãããæŽæ°ãšããŠä¿åãããŸãã ãããã£ãŠãã·ã¹ãã ãç¶ç¶çã«å®è¡ãããŠããå ŽåãTickCountããããã£ã®å€ã¯çŽ24.9æ¥éå¢å ãããŒãããå§ãŸãå€Int32.MaxValueã§çµãããŸãããã®åŸãå€Int32.MinValueã«ãªã»ãããããè² ã®æ°ã«ãªããåã³å¢å ãå§ããŸãã次ã®24.9æ¥éã¹ã¯ã©ããããŸãã
ãã®ããããã£ã®äœ¿çšã¯ãGetTickCountïŒïŒã·ã¹ãã é¢æ°ã®åŒã³åºãã«å¯Ÿå¿ããŸããããã¯ã察å¿ããã«ãŠã³ã¿ãŒã®å€ãè¿ãã ããªã®ã§ãéåžžã«é«éã§ãã ãã ããã³ã³ãã¥ãŒã¿ãŒã®ãªã¢ã«ã¿ã€ã ã¯ããã¯ã«ãã£ãŠçæãããå²ã蟌ã¿ã¯ã«ãŠã³ã¿ãŒãå¢ããããã«äœ¿çšãããããããã®ç²ŸåºŠã¯äœããªããŸãïŒ10ããªç§ïŒã
ãããã«
Windowsãªãã¬ãŒãã£ã³ã°ã·ã¹ãã ã«ã¯ãå€ãã®ã¿ã€ããŒïŒæéééã枬å®ã§ããæ©èœïŒãå«ãŸããŠããŸãã ãããã®ããã€ãã¯æ£ç¢ºã§ãããé«éã§ã¯ãªãïŒtimeGetTimeïŒãä»ã¯é«éã§ããæ£ç¢ºã§ã¯ãããŸããïŒGetTickCountãGetSystemTimeïŒããããŠMicrosoftã«ãããšã3çªç®ã¯é«éã§æ£ç¢ºã§ãã åŸè
ã«ã¯ãHPETã¿ã€ããŒãšãããã䜿çšã§ããããã«ããæ©èœïŒQueryPerformanceFrequencyãQueryPerformanceCounterïŒãå«ãŸããŸãã
Stopwatchã¯ã©ã¹ã¯ãå®éã«ã¯HPETã®ãããŒãžã©ãããŒã§ãã ãã®ã¯ã©ã¹ã䜿çšãããšãå©ç¹ïŒæéééã®ããæ£ç¢ºãªæž¬å®ïŒãšæ¬ ç¹ïŒBIOSã®ãšã©ãŒãHALã誀ã£ãçµæã«ã€ãªããå¯èœæ§ããããŸãïŒã®äž¡æ¹ããããHPETããªãå Žåããã®å©ç¹ã¯å®å
šã«å€±ãããŸãã
Stopwatchã¯ã©ã¹ã䜿çšãããã©ããã¯ããªã次第ã§ãã ãããããã®ã¯ã©ã¹ã®é·æã¯çæããããŸã 倧ããããã«æããŸãã