2008-09-22 41 views
7

Tôi là một tổng số newbie, nhưng tôi đã viết một chương trình nhỏ mà làm việc trên dây trong C# và tôi nhận thấy rằng nếu tôi đã làm một vài điều khác nhau, mã thực hiện nhanh hơn đáng kể.Kiểm tra mã của bạn để biết tốc độ?

Vì vậy, nó đã cho tôi tự hỏi, làm thế nào để bạn đi về tốc độ thực thi mã của bạn? Có bất kỳ tiện ích (miễn phí) nào không? Bạn có đi theo cách cũ với System.Timer và tự mình làm điều đó không?

Trả lời

12

Những gì bạn mô tả được gọi là lược tả hiệu suất. Có nhiều chương trình bạn có thể thực hiện việc này như Jetbrains profiler hoặc Ants profiler, mặc dù hầu hết các chương trình sẽ làm chậm ứng dụng của bạn trong khi đang trong quá trình đo lường hiệu suất của ứng dụng.

Để cuộn cuộn hồ sơ hiệu suất của riêng bạn, bạn có thể sử dụng System.Diagnostics.Stopwatch và một Console.WriteLine đơn giản, như bạn đã mô tả. Cũng cần nhớ rằng trình biên dịch C# JIT tối ưu hóa mã tùy thuộc vào loại và tần số mà nó được gọi, vì vậy hãy chơi xung quanh với các kích cỡ và phương thức khác nhau như gọi đệ quy để có cảm nhận về những gì hoạt động tốt nhất.

+0

+1: Đồng hồ bấm giờ đó là một tiện ích nhỏ tiện dụng để kiểm tra nhanh - cảm ơn! –

0

Tôi làm những việc sau: 1) Tôi sử dụng các dấu tích (ví dụ: trong VB.Net Now.ticks) để đo thời gian hiện tại. Tôi trừ các dấu tick bắt đầu từ giá trị tick đã hoàn thành và chia cho TimeSpan.TicksPerSecond để nhận được bao nhiêu giây. 2) Tôi tránh các hoạt động giao diện người dùng (như console.writeline). 3) Tôi chạy mã trên một vòng lặp đáng kể (như 100.000 lần lặp) để đưa ra các biến sử dụng/HĐH tốt nhất có thể.

11

ANTS Profiler from RedGate là một trình tạo hiệu suất thực sự tốt đẹp. dotTrace Profiler from JetBrains cũng rất tuyệt. Những công cụ này sẽ cho phép bạn xem các chỉ số hiệu suất có thể được khoan xuống từng dòng riêng lẻ.

Scree cú sút ANts Profiler: ANTS http://www.red-gate.com/products/ants_profiler/images/app/timeline_calltree3.gif

Nếu bạn muốn đảm bảo rằng một phương pháp cụ thể chỉ nằm trong một ngưỡng hoạt động cụ thể trong quá trình kiểm tra đơn vị, tôi sẽ sử dụng Stopwatch class theo dõi thời gian thực hiện một phương pháp một quặng nhiều lần trong một vòng lặp và tính trung bình và sau đó Assert so với kết quả.

+0

Chúng tôi sử dụng điều này. Nó rất hiệu quả trong việc tìm kiếm một thói quen mất 95% thời gian! –

0

Bạn có thể sử dụng lớp StopWatch theo phương pháp thời gian. Hãy nhớ rằng lần đầu tiên thường chậm do mã phải được ghi.

7

Chỉ cần nhắc nhở - hãy đảm bảo biên dịch trong Relase, chứ không phải Debug! (Tôi đã nhìn thấy sai lầm này được thực hiện bởi các nhà phát triển dày dạn - thật dễ dàng để quên).

+0

Tôi cầu xin sự khác biệt một chút. Đối với việc tìm kiếm tăng tốc, tốt nhất là làm việc trong chế độ gỡ lỗi. Khi tất cả được thực hiện với điều đó, sau đó chuyển sang chế độ phát hành. Lý do là - nếu mã đang làm những điều ngớ ngẩn như gọi một số chức năng nhất định cần thiết, hoặc phân bổ/giải phóng bộ nhớ nhiều hơn cần thiết, hoặc làm I/O bạn không nhận ra, chế độ phát hành sẽ không sửa chữa nó. Nó sẽ chỉ làm cho nó khó tìm. –

2

Mô tả của bạn là 'Điều chỉnh hiệu suất'. Khi chúng ta nói về điều chỉnh hiệu suất có hai góc với nó. (a) Thời gian đáp ứng - mất bao lâu để thực hiện một yêu cầu/chương trình cụ thể. (b) Thông lượng - Có bao nhiêu yêu cầu nó có thể thực hiện trong một giây. Khi chúng ta thường 'tối ưu hóa' - khi chúng ta loại bỏ việc xử lý không cần thiết cả thời gian đáp ứng cũng như thông lượng được cải thiện.Tuy nhiên nếu bạn có các sự kiện chờ đợi trong mã của bạn (như Thread.sleep(), I/O chờ đợi vv) thời gian phản ứng của bạn bị ảnh hưởng tuy nhiên thông lượng không bị ảnh hưởng. Bằng cách áp dụng xử lý song song (tạo nhiều luồng), chúng tôi có thể cải thiện thời gian phản hồi nhưng thông lượng sẽ không được cải thiện. Thông thường cho ứng dụng phía máy chủ cả thời gian đáp ứng và thông lượng là quan trọng. Đối với các ứng dụng máy tính để bàn (như IDE), thông lượng không quan trọng chỉ thời gian đáp ứng là quan trọng.

Bạn có thể đo thời gian phản hồi bằng 'Kiểm tra hiệu suất' - bạn chỉ cần ghi lại thời gian phản hồi cho tất cả các giao dịch chính. Bạn có thể đo lường thông lượng bằng cách 'Load Testing' - Bạn cần phải bơm yêu cầu liên tục từ đủ số lượng lớn các chủ đề/khách hàng sao cho việc sử dụng CPU của máy chủ là 80-90%. Khi chúng tôi bơm yêu cầu, chúng tôi cần duy trì tỷ lệ giữa các giao dịch khác nhau (được gọi là giao dịch hỗn hợp) - ví dụ: trong hệ thống đặt chỗ sẽ có 10 đặt chỗ cho mỗi 100 tìm kiếm. sẽ có một hủy bỏ cho mỗi 10 đặt phòng, vv

Sau khi xác định các giao dịch yêu cầu điều chỉnh thời gian đáp ứng (kiểm tra hiệu suất), bạn có thể xác định các điểm nóng bằng cách sử dụng một hồ sơ. Bạn có thể xác định các điểm nóng cho thông lượng bằng cách so sánh thời gian phản hồi * phần của giao dịch đó. Giả sử trong tìm kiếm, đặt phòng, kịch bản hủy, tỷ lệ là 89: 10: 1. Thời gian phản hồi là 0,1 giây, 10 giây và 15 giây. tải cho tìm kiếm - 0.1 * .89 = 0.089 tải cho đặt chỗ- 10 * .1 = 1 tải để hủy = 15 * .01 = 0.15 Tại đây, đặt chỗ điều chỉnh sẽ mang lại tác động tối đa đến thông lượng. Bạn cũng có thể xác định các điểm nóng cho thông lượng bằng cách lấy các bãi chứa chuỗi (trong trường hợp các ứng dụng dựa trên java) nhiều lần.

0

Có tùy chọn .NET gốc (Team Edition dành cho nhà phát triển phần mềm) có thể giải quyết một số nhu cầu phân tích hiệu suất. Từ năm 2005 đơn .NET IDE, chọn Tools-> Hiệu suất Tools-> Hiệu suất Wizard ...

[GSS có lẽ là đúng mà bạn phải có Team Edition]

0

Đây là ví dụ đơn giản cho tốc độ thử nghiệm mã. Tôi hy vọng tôi đã giúp bạn

class Program { 
    static void Main(string[] args) { 
     const int steps = 10000; 
     Stopwatch sw = new Stopwatch(); 

     ArrayList list1 = new ArrayList(); 
     sw.Start(); 
     for(int i = 0; i < steps; i++) { 
      list1.Add(i); 
     } 
     sw.Stop(); 
     Console.WriteLine("ArrayList:\tMilliseconds = {0},\tTicks = {1}", sw.ElapsedMilliseconds, sw.ElapsedTicks); 

     MyList list2 = new MyList(); 
     sw.Start(); 
     for(int i = 0; i < steps; i++) { 
      list2.Add(i); 
     } 
     sw.Stop(); 
     Console.WriteLine("MyList: \tMilliseconds = {0},\tTicks = {1}", sw.ElapsedMilliseconds, sw.ElapsedTicks); 
Các vấn đề liên quan