Tính thời gian thực hiện của một phương thức


533

Có thể trùng lặp:
Làm cách nào để đo thời gian một chức năng đang chạy?

Tôi có phương pháp lấy thời gian I / O sao chép dữ liệu từ vị trí này sang vị trí khác. Cách tốt nhất và thực tế nhất để tính thời gian thực hiện là gì? Thread? Timer? Stopwatch? Giải pháp nào khác? Tôi muốn một cái chính xác nhất, và ngắn gọn nhất có thể.

Câu trả lời:


1131

Stopwatch được thiết kế cho mục đích này và là một trong những cách tốt nhất để đo thời gian thực hiện trong .NET.

var watch = System.Diagnostics.Stopwatch.StartNew();
// the code that you want to measure comes here
watch.Stop();
var elapsedMs = watch.ElapsedMilliseconds;

Không sử dụng DateTime để đo thời gian thực hiện trong .NET.


CẬP NHẬT:

Như @ series0ne đã chỉ ra trong phần bình luận: Nếu bạn muốn một phép đo chính xác thực sự của việc thực thi một số mã, bạn sẽ phải sử dụng các bộ đếm hiệu suất được tích hợp trong hệ điều hành. Các câu trả lời sau đây có chứa một cái nhìn tổng quan tốt đẹp.


2
Chính xác, và những gì về trường hợp này: tôi có một vòng lặp foreach có ThreadPool.QueueUserWorkItem(delegate { CopyFiles(folder, dest); }); bên trong, nhưng đồng hồ bấm giờ dừng lại trước khi mọi thứ được thực hiện.
Mahdi Tahsildari

13
@DarinDimitrov - Đồng hồ bấm giờ không hoàn toàn chính xác? hãy nhớ rằng nhiễu nền .NET (như JITing) gây ra thời gian thực hiện khác nhau. Do đó, thực tế, để đo chính xác, OP nên sử dụng một trình lược tả hiệu suất.
Matthew Layton

3
@ series0ne, điểm rất tốt. Tôi sẽ cập nhật câu trả lời của tôi để bao gồm nhận xét có giá trị của bạn.
Darin Dimitrov

7
@DarinDimitrov, gần đây tôi đã có một cuộc phỏng vấn với một nhà phát triển cấp cao rất lành nghề. Ông chỉ ra cho tôi rằng sử dụng DateTimes thực sự chính xác hơn so với sử dụng Đồng hồ bấm giờ. Ông nói lý do cho điều này là Đồng hồ bấm giờ trong .NET không tính đến mối quan hệ CPU, và do đó, nếu luồng của bạn chuyển từ lõi này sang lõi khác, Đồng hồ bấm giờ không tính đến thời gian thực hiện trên các lõi khác; chỉ có một nơi mà chủ đề bắt đầu thực hiện. Ý kiến ​​của bạn như thế nào?
Matthew Layton

2
@ series0ne, những gì nhà phát triển cấp cao nói với bạn về Đồng hồ bấm giờ và DateTime là hoàn toàn đúng. Ngoại trừ việc với DateTime, bạn không có đủ độ chính xác. Vấn đề là không có lớp nào như vậy trong .NET sẽ cho phép bạn tất cả các tính năng đó.
Darin Dimitrov

75

Từ kinh nghiệm cá nhân, System.Diagnostics.Stopwatch lớp có thể được sử dụng để đo thời gian thực hiện của một phương thức, tuy nhiên, THƯỞNG : Nó không hoàn toàn chính xác!

Hãy xem xét ví dụ sau:

Stopwatch sw;

for(int index = 0; index < 10; index++)
{
    sw = Stopwatch.StartNew();
    DoSomething();
    Console.WriteLine(sw.ElapsedMilliseconds);
}

sw.Stop();

Kết quả ví dụ

132ms
4ms
3ms
3ms
2ms
3ms
34ms
2ms
1ms
1ms

Bây giờ bạn đang tự hỏi; "tại sao lần đầu tiên nó lại mất 132ms và ít hơn đáng kể thời gian còn lại?"

Câu trả lời là Stopwatchkhông bù cho hoạt động "nhiễu nền" trong .NET, chẳng hạn như JITing. Do đó, lần đầu tiên bạn chạy phương thức của mình, .NET JIT là phương thức đầu tiên. Thời gian cần thiết để làm điều này được thêm vào thời gian thực hiện. Tương tự, các yếu tố khác cũng sẽ khiến thời gian thực hiện thay đổi.

Điều bạn thực sự cần tìm kiếm cho độ chính xác tuyệt đối là Hồ sơ hiệu suất !

Hãy xem những điều sau đây:

RedGate ANTS Performance Profiler là một sản phẩm thương mại, nhưng cho kết quả rất chính xác. - Tăng hiệu suất của các ứng dụng của bạn với .NET profiling

Dưới đây là một bài viết StackOverflow về hồ sơ: - Một số trình biên dịch .NET tốt là gì?

Tôi cũng đã viết một bài viết về Hồ sơ hiệu suất bằng cách sử dụng Đồng hồ bấm giờ mà bạn có thể muốn xem - Cấu hình hiệu suất trong .NET


2
@mahditahsildari Không vấn đề gì. Rất vui vì tôi có thể giúp! :-)
Matthew Layton

41
Tôi không chắc tại sao đây là một ví dụ về sự không chính xác . Đồng hồ bấm giờ đang đo chính xác tổng chi phí của cuộc gọi đầu tiên, đây chắc chắn là những gì có liên quan đến khách hàng sẽ chạy mã này. Họ không quan tâm liệu 132 mili giây đó có được tính cho việc thực thi phương thức hay cho jitter hay không, họ quan tâm đến tổng thời gian đã trôi qua.
Eric Lippert

2
@ series0ne Nếu bạn quan tâm đến hiệu suất của một vòng lặp, thì hãy đo hiệu suất của một vòng lặp. Đừng chỉ đơn giản cho rằng làm một việc gì đó n lần có nghĩa là nó sẽ chậm hơn chính xác n lần khi thực hiện nó một lần.
Svick

3
Trước hết, mẫu mã sẽ tạo ra đầu ra với số lượng ngày càng tăng vì Đồng hồ bấm giờ không bao giờ được đặt lại trong vòng lặp. Và bởi "nên" tôi có nghĩa là nó (tôi đã kiểm tra). Vì vậy, đầu ra của bạn không phù hợp với mã. Thứ hai, khi tôi sửa mã để thực hiện Dừng / Viết / Đặt lại / Bắt đầu trong vòng lặp, phép đo đầu tiên giống như phần còn lại. Tôi đoán là DoS Something của bạn làm một cái gì đó lâu hơn trong lần đầu tiên nó chạy. JIT có thể hoặc không thể là lý do cho điều đó, nhưng không phải Đồng hồ bấm giờ đang ảnh hưởng đến phép đo. Do đó -1.
ILIA BROUDNO

2
ILIA BROUDNO hoàn toàn chính xác, tôi đã nhận được kết quả tương tự. @ series0ne, bạn có Console.WriteLine bên trong vòng lặp, viết ms cho đến nay; bởi vì bạn chỉ dừng đồng hồ SAU khi vòng lặp kết thúc, nó sẽ tăng dần theo thời gian với mỗi lần lặp, vì vậy chúng ta sẽ thấy một cái gì đó như 3, 6, 10, 12, 15 ... khi thời gian tích lũy qua các lần thực hiện.
Rui Miguel Pinheiro

29

StopWatch lớp tìm kiếm giải pháp tốt nhất của bạn.

Stopwatch sw = Stopwatch.StartNew();
DoSomeWork();
sw.Stop();

Console.WriteLine("Time taken: {0}ms", sw.Elapsed.TotalMilliseconds);

Ngoài ra, nó có một trường tĩnh gọi là Stopwatch.IsHighResolution . Tất nhiên, đây là một vấn đề phần cứng và hệ điều hành.

Cho biết bộ định thời dựa trên bộ đếm hiệu suất có độ phân giải cao.


18

Nếu bạn quan tâm đến việc hiểu hiệu suất, câu trả lời tốt nhất là sử dụng một hồ sơ.

Mặt khác, System.Diagnostics.StopWatch cung cấp bộ hẹn giờ độ phân giải cao.


Chuẩn xác! Tôi hơi nản lòng khi có rất nhiều người ở đây đã đề xuất sử dụng Đồng hồ bấm giờ, vì nó không hoàn toàn chính xác. Tuy nhiên, như bạn đã đề xuất sử dụng Trình cấu hình hiệu suất, đây là cách chính xác để làm điều đó! +1
Matthew Layton

7

Đồng hồ bấm giờ sẽ sử dụng bộ đếm độ phân giải cao

Đồng hồ bấm giờ đo thời gian đã trôi qua bằng cách đếm các đồng hồ bấm giờ trong cơ chế hẹn giờ bên dưới. Nếu phần cứng và hệ điều hành được cài đặt hỗ trợ bộ đếm hiệu suất có độ phân giải cao, thì lớp Đồng hồ bấm giờ sử dụng bộ đếm đó để đo thời gian đã trôi qua. Mặt khác, lớp Đồng hồ bấm giờ sử dụng bộ đếm thời gian hệ thống để đo thời gian đã trôi qua. Sử dụng các trường Tần số và IsHighResolution để xác định độ chính xác và độ phân giải của việc triển khai thời gian của Đồng hồ bấm giờ.

Nếu bạn đang đo IO thì số liệu của bạn có thể sẽ bị ảnh hưởng bởi các sự kiện bên ngoài và tôi sẽ lo lắng rất nhiều. tính chính xác (như bạn đã chỉ ra ở trên). Thay vào đó, tôi sẽ thực hiện một loạt các phép đo và xem xét giá trị trung bình và phân phối của các số liệu đó.


0
 using System.Diagnostics;
 class Program
 {
    static void Test1()
    {
        for (int i = 1; i <= 100; i++)
        {
            Console.WriteLine("Test1 " + i);
        }
    }
  static void Main(string[] args)
    {

        Stopwatch sw = new Stopwatch();
        sw.Start();
        Test1();
        sw.Stop();
        Console.WriteLine("Time Taken-->{0}",sw.ElapsedMilliseconds);
   }
 }
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.