2009-11-07 30 views
42

Python có cờ -O mà bạn có thể thực hiện phiên dịch với. Tùy chọn sẽ tạo ra bytecode "được tối ưu hóa" (được viết thành các tệp .pyo) và được cung cấp hai lần, nó sẽ loại bỏ các docstrings. Từ trang man của Python:Việc sử dụng chế độ tối ưu hóa cơ bản của Python là gì? (python -O)

-O Bật tối ưu hóa cơ bản. Điều này thay đổi phần mở rộng tên tệp cho các tệp được biên dịch (bytecode) từ .pyc thành .pyo. Được cung cấp hai lần, khiến tài liệu bị hủy.

hai tính năng chính của tùy chọn này khi tôi nhìn thấy nó là:

  • Strip tất cả các báo cáo khẳng định. Giao dịch này bảo vệ chống lại trạng thái chương trình bị hỏng cho tốc độ. Nhưng bạn không cần một tấn báo cáo khẳng định cho điều này để tạo sự khác biệt? Bạn có bất kỳ mã nào ở đây đáng giá không (và sane?)

  • Chặn tất cả các tài liệu. Trong ứng dụng nào là việc sử dụng bộ nhớ rất quan trọng, rằng đây là một chiến thắng? Tại sao không đẩy mọi thứ vào các mô-đun được viết bằng C?

Việc sử dụng tùy chọn này là gì? Nó có giá trị trong thế giới thực không?

+5

Bạn có thể sử dụng nó để lật đèn nháy trên bộ thử nghiệm của mình bằng cách khiến chúng lén lút bỏ qua các xác nhận. Tiếng hoan hô! Bạn đã hoàn thành dự án! (Lưu ý: Đừng làm điều này) – Shayne

Trả lời

29

Khi loại bỏ tuyên bố khẳng định: đây là một lựa chọn tiêu chuẩn trong thế giới C, nơi nhiều người cho rằng một phần định nghĩa của ASSERT là nó không chạy trong mã sản xuất. Dù tước chúng ra hay không làm cho một sự khác biệt phụ thuộc ít hơn vào bao nhiêu khẳng định có hơn trên bao nhiêu công việc những khẳng định làm:

def foo(x): 
    assert x in huge_global_computation_to_check_all_possible_x_values() 
    # ok, go ahead and use x... 

Hầu hết khẳng định không phải là như vậy, tất nhiên, nhưng điều quan trọng là phải nhớ rằng bạn có thể làm những việc như thế.

Đối với việc rút gọn tài liệu, nó có vẻ như một sự trì hoãn kỳ lạ từ một thời gian đơn giản, mặc dù tôi đoán có những môi trường hạn chế về bộ nhớ, nơi nó có thể tạo sự khác biệt.

+0

lịch sử là quan trọng, điểm tốt. Tuy nhiên, tôi không muốn xem các ví dụ đồ chơi, tôi muốn xem những gì khẳng định được sử dụng trong mã thực tế và nếu nó tạo ra sự khác biệt. – u0b34a0f6ae

+17

Tốc độ bộ nhớ đang tăng chậm hơn tốc độ CPU, đặc biệt * nếu bạn cho rằng chúng tôi tiếp tục thêm bộ xử lý nhanh hơn việc thêm băng thông bộ nhớ. Vì vậy, bộ nhớ là đĩa mới và bộ đệm L2 là bộ nhớ mới. Và L2 cache là * nhỏ * (so với bộ nhớ), và chúng thực sự ngày càng nhỏ hơn. (Core2 có 6144KiB, i7 chỉ 256KiB, ví dụ.) Vì vậy, đếm byte thực sự trở nên hữu ích một lần nữa. –

+2

OpenGL libs như PyOpenGL và pyglet thực hiện một số xác nhận kiểm tra an toàn rất tốn kém khi chạy trừ khi bạn chỉ định -O. –

3

Bạn đã tìm ra khá nhiều điều: Thực tế không có gì cả. Bạn hầu như không bao giờ thấy tốc độ hoặc bộ nhớ tăng lên, trừ khi bạn đang làm tổn thương nghiêm trọng đến RAM.

+0

hoặc 'if __debug__: r = long_running_function(); khẳng định n - 0,01 DylanYoung

5

Tôi tưởng tượng rằng người dùng nặng nhất của -Opy2exepy2app và tương tự.

Cá nhân tôi chưa bao giờ tìm thấy sử dụng trực tiếp cho số -O.

+0

và * tại sao * không sử dụng py2exe? – u0b34a0f6ae

+4

Khi tạo tệp thực thi độc lập, không cần phải có tài liệu. Chúng chỉ chiếm không gian trong bộ nhớ. – gnud

7

Nếu bạn có xác nhận trong mã được gọi thường xuyên (ví dụ: trong vòng lặp bên trong), việc tách chúng có thể tạo ra sự khác biệt. Ví dụ cực đoan:

$ python -c 'import timeit;print timeit.repeat("assert True")' 
[0.088717937469482422, 0.088625192642211914, 0.088654994964599609] 
$ python -O -c 'import timeit;print timeit.repeat("assert True")' 
[0.029736995697021484, 0.029587030410766602, 0.029623985290527344] 

Trong trường hợp thực tế, khoản tiết kiệm thường ít hơn nhiều.

Tước các tài liệu có thể làm giảm kích thước mã của bạn và do đó làm việc của bạn.

Trong nhiều trường hợp, tác động hiệu suất sẽ không đáng kể, nhưng như thường lệ với tối ưu hóa, cách duy nhất để chắc chắn là đo lường.

+1

câu hỏi này là về mã thế giới thực. btw, điều này là thực tế hơn: 'python -mtimeit" "" khẳng định (True) "' (thiết lập trong đối số đầu tiên) – u0b34a0f6ae

+1

Điều này có vẻ là một ví dụ lạ đối với tôi. Bạn giảm bớt mã nhỏ đến mức không tồn tại - điều đó không thể hiện nhiều về tốc độ thực tế mà tôi nghĩ.Một trường hợp sử dụng thực tế sẽ là một hoạt động tạo ra rất nhiều giả định đắt tiền để kiểm tra so với thực hiện thao tác, nhưng bạn tin rằng chúng phải luôn được thỏa mãn. Ví dụ, nếu tôi cố gắng trả lại gốc rễ của một parabola, tôi có thể kiểm tra b ** 2 - 4 * a * c> 0 để đảm bảo rễ thực, nếu đó là những gì tôi quan tâm. Nhiều công thức hữu ích có rất nhiều các ràng buộc. –

+2

Ngoài ra, 'assert' là một câu lệnh mà tôi muốn sử dụng như" 'khẳng định True'", không phải 'assert (True)'. Điều này trở nên quan trọng khi bạn thêm thông điệp, như 'assert a == b," Phải là true "' là rất khác với 'assert (a == b," Phải là true ")', và đặc biệt sau này luôn chuyển . –

6

Tôi chưa bao giờ gặp phải lý do chính đáng để sử dụng -O. Tôi đã luôn luôn giả định mục đích chính của nó là trong trường hợp tại một số điểm trong tương lai một số tối ưu hóa có ý nghĩa được thêm vào.

+3

Vâng, nó làm một vài điều, họ chỉ không thường là tất cả những gì hữu ích. –

39

Sử dụng khác cho cờ -O là giá trị của biến số dựng sẵn __debug__ được đặt thành False.

Vì vậy, về cơ bản, mã của bạn có thể có rất nhiều "gỡ rối" những con đường như:

if __debug__: 
    # output all your favourite debugging information 
    # and then more 

mà khi chạy dưới -O, thậm chí sẽ không được đưa vào như bytecode trong file .pyo; một người đàn ông nghèo của C-ish #ifdef.

Hãy nhớ rằng tài liệu đang bị xóa chỉ khi cờ là -OO.

+1

cũng khiến tôi nghĩ về một vấn đề cơ bản khác với -O: Nói chung, đó là vai trò của nhà phát triển để quyết định điều gì xảy ra với/không có chế độ tối ưu hóa, nhưng người dùng có thể quyết định cách trình thông dịch python được gọi, bình thường! Điều này làm cho ví dụ của bạn bên cạnh vô dụng vì bạn không thể dựa vào một chế độ cụ thể đang được sử dụng. – u0b34a0f6ae

+22

Chà. Tôi nghĩ bạn muốn biết sử dụng thế giới thực của tùy chọn này là gì. Cảm ơn vì đã tìm câu trả lời của tôi bên cạnh vô dụng. Nhân tiện, nếu bạn muốn ai đó biện minh cho các lựa chọn của Guido và phần còn lại của nhóm lõi Python, bạn không nên đặt câu hỏi ở đây; cuối cùng, bạn * có thể * dựa vào một chế độ cụ thể đang được sử dụng, lập trình viên có thể kiểm soát việc tối ưu hóa có được sử dụng hay không; hỏi một câu hỏi có liên quan trong SO như thế nào. Tôi xin tuyên bố giả định của bạn bên cạnh sai và thời gian của tôi bên cạnh bị mất. Chúc mừng. Xin lỗi vì đã làm bạn thất vọng. – tzot

+3

Không có lý do gì để tôi thất vọng khi nhận được nhiều câu trả lời cho câu hỏi của mình - Tôi thích các cuộc hội thoại trong stackoverflow. Ý tôi là những gì tôi nói nhưng tôi nói về ví dụ bạn đã trình bày. Thực tế là bạn đã thể hiện nó hoặc bản thân bạn không bị đánh giá tiêu cực chút nào. – u0b34a0f6ae

1

Nhưng bạn không cần một tấn câu khẳng định cho điều này để tạo sự khác biệt? Bạn có bất kỳ mã nào ở đây đáng giá không (và sane?)

Ví dụ, tôi có một đoạn mã có đường dẫn giữa các nút trong biểu đồ. Tôi có một tuyên bố khẳng định ở phần cuối của các chức năng để kiểm tra xem các con đường không chứa các bản sao:

assert not any(a == b for a, b in zip(path, path[1:])) 

Tôi thích peace of mind and clarity rằng tuyên bố đơn giản này mang lại cho quá trình phát triển. Trong quá trình sản xuất, mã xử lý một số đồ thị lớn và dòng đơn này có thể chiếm tới 66% thời gian chạy. Chạy với -O do đó sẽ tăng tốc đáng kể.

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