คลาส Stopwatch ใน namespace System.Diagnostics ใช้สำหรับวัดเวลาที่ผ่านไป (Elapsed time) อย่างแม่นยำสูง เหมาะสำหรับ Benchmarking, Profiling และการวัดประสิทธิภาพโค้ด ใช้ High-Resolution Timer ของระบบปฏิบัติการ
คุณสมบัติหลัก
| คุณสมบัติ | ชนิด | คำอธิบาย |
|---|---|---|
Elapsed | TimeSpan | เวลาที่ผ่านไปในรูปแบบ TimeSpan |
ElapsedMilliseconds | long | เวลาที่ผ่านไปเป็นมิลลิวินาที |
ElapsedTicks | long | จำนวน Ticks ที่ผ่านไป (ความแม่นยำสูงสุด) |
IsRunning | bool | สถานะว่ากำลังนับอยู่หรือไม่ |
โค้ดตัวอย่างสมบูรณ์
using System;
using System.Diagnostics;
using System.Linq;
public class Demo
{
public static void Main()
{
// เริ่มจับเวลา
var sw = Stopwatch.StartNew();
// จำลองงานหนัก
int sum = 0;
for (int i = 0; i < 1000000; i++)
{
sum += i;
}
// หยุดนับ (ถ้าไม่หยุด จะนับต่อไปเรื่อยๆ)
sw.Stop();
Console.WriteLine($"Elapsed: {sw.Elapsed}");
Console.WriteLine($"ElapsedMilliseconds: {sw.ElapsedMilliseconds} ms");
Console.WriteLine($"ElapsedTicks: {sw.ElapsedTicks} ticks");
Console.WriteLine($"IsRunning: {sw.IsRunning}");
Console.WriteLine($"Frequency: {Stopwatch.Frequency} ticks/second");
Console.WriteLine($"IsHighResolution: {Stopwatch.IsHighResolution}");
// แปลง Ticks เป็นวินาที
double seconds = (double)sw.ElapsedTicks / Stopwatch.Frequency;
Console.WriteLine($"คำนวณจาก Ticks: {seconds:F6} วินาที");
}
}
ผลลัพธ์ตัวอย่าง
Elapsed: 00:00:00.0012345
ElapsedMilliseconds: 1 ms
ElapsedTicks: 312456 ticks
IsRunning: False
Frequency: 10000000 ticks/second
IsHighResolution: True
คำนวณจาก Ticks: 0.031246 วินาที
รูปแบบการใช้งานต่างๆ
1. ใช้ StartNew() (แนะนำ - เริ่มทันที)
var sw = Stopwatch.StartNew();
DoWork();
sw.Stop();
Console.WriteLine(sw.ElapsedMilliseconds);
2. ใช้ Constructor แล้ว Start() เอง
var sw = new Stopwatch();
sw.Start();
DoWork();
sw.Stop();
3. วัดเวลาหลายช่วง (Pause/Resume)
var sw = Stopwatch.StartNew();
DoPhase1();
sw.Stop(); // หยุดชั่วคราว
WaitForInput();
sw.Start(); // เริ่มนับต่อ (สะสม)
DoPhase2();
sw.Stop();
Console.WriteLine($"เวลารวม: {sw.ElapsedMilliseconds} ms");
4. วัดเวลาแยกช่วง (Lap timing)
var sw = Stopwatch.StartNew();
for (int i = 1; i <= 5; i++)
{
DoWork();
long lap = sw.ElapsedMilliseconds;
Console.WriteLine($"รอบ {i}: {lap} ms");
sw.Restart(); // รีเซ็ตและเริ่มใหม่
}
การใช้งานจริง: Benchmarking
public static void Benchmark(Action action, int iterations = 1000)
{
// Warm up
for (int i = 0; i < 10; i++) action();
var sw = Stopwatch.StartNew();
for (int i = 0; i < iterations; i++) action();
sw.Stop();
double avgMs = (double)sw.ElapsedMilliseconds / iterations;
Console.WriteLine($"เฉลี่ย: {avgMs:F4} ms ต่อครั้ง ({iterations} รอบ)");
}
// ใช้งาน
Benchmark(() => {
// โค้ดที่ต้องการวัด
var list = Enumerable.Range(1, 1000).ToList();
var sum = list.Sum();
});
ข้อควรระวัง
- ต้องเรียก
Stop()เมื่อจบการวัด มิฉะนั้นจะนับต่อไปเรื่อยๆ ElapsedTicksใช้Stopwatch.Frequencyแปลงเป็นวินาที (ไม่ใช่ DateTime.Ticks)- บนระบบบางระบบ
IsHighResolutionอาจเป็น false (ใช้ system timer แทน) - สำหรับ Micro-benchmarking จริง ควรใช้
BenchmarkDotNetlibrary - Stopwatch ไม่ได้วัด CPU Time - วัด Wall-clock time