Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> C#

คลาส Stopwatch ใน C#: การวัดเวลาที่ผ่านไปอย่างแม่นยำ

คลาส Stopwatch ใน namespace System.Diagnostics ใช้สำหรับวัดเวลาที่ผ่านไป (Elapsed time) อย่างแม่นยำสูง เหมาะสำหรับ Benchmarking, Profiling และการวัดประสิทธิภาพโค้ด ใช้ High-Resolution Timer ของระบบปฏิบัติการ

คุณสมบัติหลัก

คุณสมบัติชนิดคำอธิบาย
ElapsedTimeSpanเวลาที่ผ่านไปในรูปแบบ TimeSpan
ElapsedMillisecondslongเวลาที่ผ่านไปเป็นมิลลิวินาที
ElapsedTickslongจำนวน Ticks ที่ผ่านไป (ความแม่นยำสูงสุด)
IsRunningboolสถานะว่ากำลังนับอยู่หรือไม่

โค้ดตัวอย่างสมบูรณ์

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 จริง ควรใช้ BenchmarkDotNet library
  • Stopwatch ไม่ได้วัด CPU Time - วัด Wall-clock time