2010-11-03 38 views
19

Ngoài ruby-prof và lớp Benchmark cốt lõi, bạn sử dụng những gì để cấu hình mã Ruby của bạn? Đặc biệt, làm thế nào để bạn tìm thấy các nút cổ chai trong mã của bạn? Nó gần như cảm thấy như tôi cần phải làm việc trên công cụ nhỏ của riêng tôi chỉ để tìm ra nơi mà tất cả thời gian đang được chi tiêu trong mã của tôi.Biên tập mã Ruby

Tôi nhận ra ruby-prof cung cấp điều này, nhưng kết quả đầu ra rất khó hiểu và không dễ dàng tìm ra các khối thực sự của mã của bạn là nguồn gốc của vấn đề (nó cho bạn biết phương thức nào gọi mất nhiều thời gian nhất). Vì vậy, tôi không thực sự nhận được nhiều như nó như tôi muốn, và đã không thực sự có thể tận dụng nó.

Có lẽ tôi đang làm sai? Có lựa chọn thay thế nào không? Google tìm kiếm không mang lại bất cứ điều gì cho tôi.

+1

Bạn có gặp những vấn đề tương tự mà tôi đã có trong [Có thể bỏ qua phương pháp không thích hợp khi profiling ruby applications?] (http://stackoverflow.com/questions/2241491/is-it-possible-to-ignore-irrelevant-methods-when-profiling-ruby-applications). Tôi đã tìm ra tùy chọn loại bỏ phương pháp của ruby-prof. –

Trả lời

6

Rất nhiều trình thu thập dữ liệu giống như vậy. Những điều bạn cần biết không phải là trong đó chương trình dành thời gian của mình, nhưng lý do tại sao. Any references on Dynamic Code Analysis?

THÊM: Here's how Tôi tìm thấy "nút cổ chai" trong mã của mình. (Tôi ghét từ đó.) Here's a list lý do tại sao.

Hoàn toàn tự nhiên khi giả định rằng để tìm "nút cổ chai" bạn phải bằng cách nào đó thực hiện rất nhiều đo lường. Rất tự nhiên là gần như tất cả các trình biên dịch đều dựa trên nó.

Thực ra, việc tìm và đo không phải là vấn đề tương tự. Đo lường là cần thiết để xem nếu những gì bạn tìm thấy (và cố định) tạo sự khác biệt. Tìm thấy những gì để sửa chữa, với tôi, giống như gỡ lỗi hơn đo lường.

Cách đơn giản nhất để giải thích là bắt đầu từ vòng lặp vô hạn hoặc gần như vô hạn. Làm thế nào để bạn tìm thấy nó? Bạn tạm dừng nó và nhìn vào ngăn xếp, phải không? bởi vì bạn biết vấn đề ở đâu đó trên ngăn xếp. Bạn chỉ cần tạm dừng nó một lần, và sau đó bạn cần phải nghiên cứu mã trên ngăn xếp. Tạm dừng nó một vài lần nếu bạn muốn chắc chắn rằng bạn đã tìm thấy nó.

Giả sử mã chỉ mất gấp đôi thời gian cần thiết. Điều đó có nghĩa là khi bạn tạm dừng nó, có 50% cơ hội bạn sẽ thấy nó làm điều không cần thiết. Nếu bạn tạm dừng nó và nhìn vào nó 10 lần, bạn sẽ bắt nó trong hành động khoảng 5 lần. Trong thực tế, ngay sau khi bạn thấy nó làm một cái gì đó bạn có thể tối ưu hóa trên ít nhất là 2 mẫu, bạn đã tìm thấy một "nút cổ chai". Sửa chữa nó, đo tốc độ, hiển thị nó, và lặp lại.

Ngay cả khi vấn đề lớn nhất của bạn không phải là rất lớn, phương pháp này cuối cùng sẽ tìm thấy nó. Ngoài ra, có hiện tượng phóng đại, ở đó các vấn đề nhỏ trở nên dễ tìm hơn sau khi bạn đã xóa các vấn đề lớn hơn. Điều đó cho phép bạn tiếp tục cho đến khi mã gần như tối ưu.

P.S. Sau khi bạn đã thực hiện việc này, vẫn có thể có cơ hội để tăng tốc. Ví dụ, thuật toán tối ưu hóa có thể phụ thuộc vào sự ổn định số. Các kiến ​​trúc hướng tin nhắn có thể làm cho việc theo dõi tại sao mã đang được thực hiện khó khăn hơn. Trong phần mềm thời gian thực, một vấn đề về hiệu suất chỉ thỉnh thoảng xảy ra và ít dễ lấy mẫu hơn. Điều này đòi hỏi sự thông minh hơn. Rơi xuống chỉ đo không làm điều đó.

+1

Cảm ơn vì điều đó, tôi sẽ thử phương pháp này. Tôi cũng tìm thấy perftools, đó là một profiler lấy mẫu và tạo ra các biểu đồ cuộc gọi như sau: http://perftools-rb.rubyforge.org/examples/rubygems.gif - Bạn có nghĩ rằng làm theo cách thủ công cho bit thông tin bổ sung không cung cấp nhiều lợi thế thực sự? – ehsanul

+0

@ehsanul: Tuyệt đối, như được giải thích ở điểm 3 của giải pháp thay thế cho liên kết Gprof. Nhưng không chỉ dùng từ ngữ của tôi cho nó: http://stackoverflow.com/questions/2624667/whats-a-very-easy-c-profiler-vc/2624725#2624725 http://stackoverflow.com/questions/ 2473666/mẹo-cho-tối ưu hóa-c-net-chương trình/2474118 # 2474118 Nó giống như so sánh một chiếc xe hào nhoáng với một chiếc máy bay xấu xí. Một vẻ đẹp, nhưng người kia lại đưa bạn đến đó. –

+0

@MikeDunlavey: câu hỏi của tyro: làm thế nào để bạn làm gián đoạn ứng dụng ruby ​​và nhận được backtrace? Bạn có thể chụp SIGINT để vào trình gỡ lỗi ruby ​​không? Hay bạn làm mọi thứ dưới gdb? –

2

Đây là câu hỏi của riêng tôi, nhưng tôi tìm thấy một công cụ rất tuyệt vời cho hồ sơ mà tôi cần phải thêm nó ở đây:

http://samsaffron.com/archive/2013/03/19/flame-graphs-in-ruby-miniprofiler

Flamegraphs làm cho nguồn gốc của vấn đề hiệu suất đáng kinh ngạc rõ ràng, tương đối để nhìn vào backtraces.

+1

Tôi thừa nhận nhìn vào backtraces là tẻ nhạt và xấu xí, và ngọn lửa đồ thị là sexy, nhưng backtraces sẽ tìm thấy một superset của speedups, so với ngọn lửa đồ thị. [* Đây là lý do. *] (Http://stackoverflow.com/a/27867426/23771) –

5

Để thực sự xem xét mã của bạn, hãy thử stackprof.

Đây là giải pháp nhanh về cách sử dụng: Cài đặt đá quý: gem install stackprof. Trong mã của bạn thêm: require 'stackprof' và bao quanh phần mà bạn muốn kiểm tra với điều này:

StackProf.run(mode: :cpu, out: 'stackprof-output.dump') do {YOUR_CODE} end

Sau khi chạy kịch bản ruby ​​của bạn đi kiểm tra đầu ra tại nhà ga với stackprof stackprof.dump:

Mode: cpu(1000) 
Samples: 9145 (1.25% miss rate) 
GC: 448 (4.90%) 

TOTAL (pct)  SAMPLES (pct)  FRAME 
    236 (2.6%)   231 (2.5%)  String#blank? 
    546 (6.0%)   216 (2.4%)  ActiveRecord::ConnectionAdapters::Mysql2Adapter#select 
    212 (2.3%)   199 (2.2%)  Mysql2::Client#query_with_timing 
    190 (2.1%)   155 (1.7%)  ERB::Util#html_escape`` 

đây bạn có thể thấy tất cả các phương pháp của bạn đòi hỏi rất nhiều thời gian. Bây giờ là phần tuyệt vời: Để khoan chỉ làm stackprof stackprof.dump --method String#blank? và bạn sẽ có được đầu ra cho các phương pháp cụ thể:

String#blank? (lib/active_support/core_ext/object/blank.rb:80) 
    samples: 231 self (2.5%)/ 236 total (2.6%) 
    callers: 
    112 ( 47.5%) Object#present? 
    code: 
            | 80 | def blank? 
    187 (2.0%)/ 187 (2.0%) | 81 |  self !~ /[^[:space:]]/ 
            | 82 | end 

Và bạn có thể khá dễ dàng hình dung ra phần nào của mã của bạn mất rất nhiều thời gian để chạy.

Nếu bạn muốn có được đầu ra trực quan, hãy thực hiện stackprof stackprof.dump --graphviz >> stackprof.dot và sử dụng graphviz (brew install graphviz) dot- T pdf -o stackprof.pdf stackprof.dot có được đầu ra PDF đẹp, làm nổi bật các phương pháp mất nhiều thời gian để chạy.

Các vấn đề liên quan