2010-08-25 7 views
10

Tôi đang điều chỉnh ứng dụng sử dụng nhiều máy phát để tạo ra các kết quả để cung cấp giao diện web.py.Tạo các trình tạo mã hóa Python

Cho đến nay, tôi có thể kết thúc cuộc gọi đến báo cáo vòng lặp và báo cáo sản xuất đầu ra trong một hàm và gọi đó bằng cách sử dụng cProfile.run() hoặc runctx(). Về mặt lý thuyết:

def output(): 
    for value in generator(): 
     print(value) 

cProfile.run('output()') 

Trong web.py, tôi phải quấn nó theo cách sau, kể từ khi tôi muốn ngay lập tức tạo ra từ việc tính toán có khả năng kéo dài trong mỗi bước lặp sử dụng yield:

class index: 
    def GET(self): 
     for value in generator(): 
      yield make_pretty_html(value) 

Có cách nào để cấu hình tất cả các cuộc gọi đến máy phát như trong ví dụ đầu tiên khi nó được sử dụng như trong lần thứ hai?

+0

Bạn có đơn giản muốn đo toàn bộ cuộc gọi hàm thay vì chỉ một lần lặp? Như trong 'cProfile.run ('list (index(). GET())')'? –

+0

Về bản chất, đây là những gì cho vòng lặp hoàn thành. Vấn đề ở đây là tôi không có quyền kiểm soát các cuộc gọi đến 'GET()', nó được xử lý bởi 'web.py'. Hơn nữa, tôi không nghĩ rằng đầu ra sẽ được sản xuất theo cách đó nữa (sử dụng giá trị trả về). –

Trả lời

5

cuối cùng tôi đã tìm thấy một giải pháp. Giá trị trả về của hồ sơ qua here.

import cProfile 
import pstats 
import glob 
import math 

def gen(): 
    for i in range(1, 10): 
     yield math.factorial(i) 

class index(object): 
    def GET(self): 
     p = cProfile.Profile() 

     it = gen() 
     while True: 
      try: 
       nxt = p.runcall(next, it) 
      except StopIteration: 
       break 
      print nxt 

     p.print_stats() 

index().GET() 

tôi cũng có thể kết hợp nhiều kết quả hồ sơ như vậy (khi tôi bắt đầu ra tên tập tin duy nhất) qua documentation và cửa hàng/phân tích chúng cộng lại.

0

Bạn có thể sử dụng time.time() để cấu hình các phần bạn quan tâm không? Chỉ cần lấy thời gian hiện tại và trừ đi lần cuối bạn thực hiện phép đo.

+0

Tôi đã nhận được tổng thời gian, nhưng "Đang xử lý mất 5.382 giây" không đủ cụ thể để tìm các tắc nghẽn hiệu suất. Tôi sử dụng một chuỗi máy phát điện khá lớn và phân nhánh trong nội bộ và dự định lưu trữ dữ liệu đầu vào của người dùng và hiệu suất kết quả để phân tích sau này. Tôi có một số chức năng mất trung bình 0,000 giây mỗi cuộc gọi nhưng có thể được gọi là hàng chục nghìn lần. –

+0

Trong trường hợp đó, bạn có thể có một số nguyên truy cập cho mỗi thực hiện các chức năng và chỉ thực hiện một phép đo mỗi lần thực hiện 1000? Bạn có thể đo khối mã theo cách này thay thế và thu hẹp các nút cổ chai. Tôi nhận ra nó có thể hơi tẻ nhạt, tùy thuộc vào mã. – karpathy

1

Có vẻ như bạn đang cố gắng sắp xếp từng cuộc gọi đến 'tiếp theo' trên trình tạo? Nếu vậy, bạn có thể quấn máy phát điện của bạn trong một máy phát điện profiling. Một cái gì đó như thế này, nơi phần nhận xét tắt sẽ được gửi kết quả đến một bản ghi hoặc cơ sở dữ liệu.

 
def iter_profiler(itr): 
    itr = iter(itr) 
    while True: 
    try: 
     start = time.time() 
     value = itr.next() 
     end = time.time() 
    except StopIteration: 
     break 
    # do something with (end - stop) times here 
    yield value 
 

Sau đó, thay vì instantiating máy phát điện của bạn như generator() bạn sẽ sử dụng iter_profiler(generator())

+1

cách khác, bạn có thể áp dụng phiên bản sửa đổi của nó làm trang trí theo định nghĩa của trình tạo. – aaronasterling

+0

Về cơ bản, bạn nói đúng. Tôi đã tính số mili giây giữa trước và sau vòng lặp 'for' trong ví dụ thứ hai của bài đăng gốc, vì vậy tôi đã có thông tin này (mặc dù tôi đếm nhiều hơn một chút so với bạn, nhưng một vài triệu không quan trọng). Tuy nhiên, tôi quan tâm nhiều hơn cho các "điểm nóng" trong mã của tôi (nơi mà thời gian tính toán chết đi?) Hơn chính xác trong số hàng tá kết quả mất nhiều thời gian hơn các kết quả khác. Vì vậy, tôi đã hy vọng cho một giải pháp dựa trên 'profile/cProfile' (mà không tạo ra một báo cáo cho mỗi kết quả). Nếu có một cách để hợp nhất các báo cáo profiler, đó sẽ là cách để đi. –