Khi nào tôi nên quan tâm đến hiệu suất?


16

Trong thời gian dài nhất ở những nơi như kênh IRC của Java , SO và những nơi khác tôi đã được nói điều gì đó dọc theo dòng chữ "Lo lắng về cách mã trông như thế nào và khả năng đọc / hiểu của nó bây giờ, và hiệu suất sau này nếu cần thiết". Vì vậy, trong thời gian dài nhất, tôi thực sự không phải là OCD về hiệu suất cho các ứng dụng web hoặc máy tính để bàn nhỏ của mình, chỉ loại bỏ rõ ràng là không hiệu quả.

Hầu hết các câu trả lời là "Điều gì về khả năng mở rộng?". Đó là một điểm hợp pháp, nhưng nếu ứng dụng của tôi chỉ được xây dựng để phân tích, giả sử, các tệp dài 10.000 dòng, tôi có nên biến mã của mình thành một mớ hỗn độn cho một tỷ lệ nhỏ những người sẽ chuyển sang tệp 1.000.000 dòng không?

Câu hỏi chính của tôi là khi nào tôi nên giao dịch các cách dễ dàng nhưng hơi kém hiệu quả để thực hiện các nhiệm vụ cho những con thú to lớn phức tạp, thực hiện mọi việc cực kỳ nhanh chóng nhưng phá hủy mọi cách nâng cấp có thể và làm cho mã quá khó và dễ bị viết lại bởi nhà phát triển tiếp theo?

Câu trả lời:


23

Lo lắng về hiệu suất khi nó trở thành một vấn đề.

Nếu bạn viết một ứng dụng nhỏ để xử lý 10.000 tệp dòng và bạn nhận được tệp 1.000.000 dòng mỗi tệp thứ 100, có thể không mất nhiều thời gian để xử lý một tệp đó. Tuy nhiên, nếu bạn thường xuyên nhận được các tệp lớn hơn 5-10 lần so với ban đầu và ứng dụng của bạn mất quá nhiều thời gian để thực hiện công việc của nó, thì bạn bắt đầu lập hồ sơ và tối ưu hóa.

Bây giờ, tôi đã nói "quá lâu để thực hiện công việc của mình". Đó là tùy thuộc vào người dùng hoặc tổ chức tài trợ để quyết định. Nếu tôi đang thực hiện một nhiệm vụ và tôi phải mất 5 phút để làm điều gì đó khi tôi mất 3 phần mềm mà không có phần mềm hoặc với một công cụ khác, tôi có thể gửi báo cáo lỗi hoặc yêu cầu bảo trì để cải thiện điều đó.

Nếu bạn là người dùng, bạn muốn phần mềm của mình mất bao lâu để thực hiện công việc của nó tùy thuộc vào bạn - chỉ bạn mới có thể quyết định xem bạn muốn nó được thực hiện nhanh hơn hay bạn sẵn sàng chờ đợi lâu hơn để có mã dễ đọc hơn.



Tôi bắt đầu định hình và tối ưu hóa Nếu 1) công việc kéo dài 2) một trong những tài nguyên phần cứng ở mức tối đa (ví dụ: 100% cpu)
A. Binzxxxxxx

10

Câu hỏi chính của tôi là khi nào tôi nên giao dịch các cách dễ dàng nhưng hơi kém hiệu quả để thực hiện các nhiệm vụ cho những con thú to lớn phức tạp, thực hiện mọi việc cực kỳ nhanh chóng nhưng phá hủy mọi cách nâng cấp có thể và làm cho mã quá khó và dễ bị viết lại bởi nhà phát triển tiếp theo?

Đây thường là một sự phân đôi giả . Bạn có thể viết mã hiệu quả tuyệt vời, dễ đọc và duy trì. Bạn có thể viết tuyệt vời không hiệu quả, đống lộn xộn không thể nhầm lẫn.

Khi xử lý các vấn đề về hiệu suất, tôi thường cố gắng nghĩ về vấn đề kinh doanh mà tôi đang giải quyết. Phần mềm của tôi sẽ ứng xử như thế nào khi khách hàng của tôi sử dụng nó. Hiệu suất ứng dụng của tôi có làm Jacob Nielsen hài lòng không?


5
++ NỀN TẢNG SAU! Họ sẽ không bao giờ học? Khi bạn tìm và khắc phục sự cố về hiệu suất, mã không chỉ nhanh hơn mà còn tốt hơn . Tôi chỉ tiếc rằng tôi có nhưng một upvote để cung cấp!
Mike Dunlavey

+1 để viết rằng đó là một sự phân đôi giả ... không phải lúc nào cũng vậy, nhưng thông thường.
Dan Rosenstark

1
-1 để viết nó thường là phân đôi giả - thực tế là, nó thường đúng và chỉ trong những trường hợp hiếm hoi là phân đôi giả. Trong hơn 30 năm trong sự nghiệp lập trình của tôi, tôi đã thấy quá nhiều tối ưu hóa hiệu năng "có chủ đích", điều này thực tế làm cho mã khó hiểu và duy trì hơn (và thường tối ưu hóa một cái gì đó hoàn toàn không cần thiết để tối ưu hóa).
Doc Brown

5

Một sự thật mà tôi đã chọn học vi xử lý ở trường đại học đã ở lại với tôi: "Làm cho trường hợp phổ biến nhanh chóng. Làm cho trường hợp không phổ biến chính xác."

Miễn là bạn chỉ có một tỷ lệ nhỏ người dùng bóp nghẹt mã của bạn với hai đơn đặt hàng có cường độ lớn hơn số lượng lớn để xử lý, đừng đổ mồ hôi. Hãy chắc chắn rằng nó xử lý đầu vào một cách chính xác nếu họ cho nó đủ lâu và không để bất cứ thứ gì bị hỏng thành vô dụng nếu họ giết công việc trước khi nó kết thúc.

Nhưng, một khi ngày càng có nhiều người bắt đầu sử dụng nó theo cách đó (hoặc bắt đầu nói với bạn "Bạn biết đấy, tôi rất thích sử dụng công cụ mà bạn đã viết trên các báo cáo TPS hàng tuần của tôi, nhưng phải mất cả ngày" bạn bắt đầu xem xét giao dịch dễ dàng bảo trì để tăng hiệu suất.


1

Câu hỏi chính của tôi là khi nào tôi nên giao dịch các cách dễ dàng nhưng hơi kém hiệu quả để thực hiện các nhiệm vụ cho những con thú to lớn phức tạp, thực hiện mọi việc cực kỳ nhanh chóng nhưng phá hủy mọi cách nâng cấp có thể và làm cho mã quá khó và dễ bị viết lại bởi nhà phát triển tiếp theo?

"Lo lắng về cách mã trông như thế nào và tính dễ đọc / dễ hiểu của nó bây giờ, và hiệu suất sau này nếu thực sự cần thiết" là cách dễ dàng, và nói chung là không có ích. một thiết kế tốt sẽ dễ bảo trì, dễ đọc và hiệu quả.

hiệu suất là một thành phần phổ biến của một thiết kế tốt. nếu chương trình của bạn chậm và lãng phí, nó thực sự không thể tái sử dụng. Khi bạn cần sửa chữa mớ hỗn độn đó , bạn buộc phải cập nhật cho khách hàng của mình, trừ khi quá thời gian để họ cập nhật. chương trình chậm chạp đó trở thành mớ hỗn độn lớn quá tốn kém để cải thiện. sau đó họ chọn một phương án thay thế không phù hợp với nhu cầu của họ. chẩn đoán, cập nhật và xử lý các tác dụng phụ của cải tiến đối với một thiết kế xấu thường vượt xa thời gian phát triển ban đầu để viết nó hiệu quả, hoạt động chính xác và có thiết kế tốt về mặt thể chất. chương trình đó có khả năng tái sử dụng cao và yêu cầu bảo trì thấp (thắng).

vì vậy, câu trả lời ngắn gọn cho câu hỏi của bạn là "đừng lãng phí. hãy viết để sử dụng lại. Bạn có thể lười biếng khi tạo mẫu / phát triển bằng chứng về các khái niệm, nhưng đừng sử dụng nguyên mẫu đó cho mã sản xuất."

lưu ý và tránh các thiết kế lãng phí khi viết chương trình và chương trình sản xuất mà bạn định sử dụng lại. trong quá trình thực hiện là thời điểm lý tưởng để viết chương trình của bạn để không lãng phí - bạn có một ý tưởng rõ ràng về các chi tiết và hoạt động của nó, và nó thực sự đau đớn và không hiệu quả để khắc phục sau khi nó được viết. Cuối cùng, rất nhiều người tin rằng một chút sơ lược (có thể) hoặc nếu có vấn đề là không thỏa đáng, khi thường mất quá nhiều thời gian để thiết kế lại / thay đổi và sự thiếu hiệu quả rất nhiều và phổ biến đến mức bạn không hiểu chương trình cũng dựa trên kết quả của một hồ sơ. Cách tiếp cận này mất ít thời gian trong quá trình thực hiện và (giả sử bạn đã thực hiện đủ số lần này) thường dẫn đến một thiết kế nhanh hơn nhiều lần và có thể tái sử dụng trong nhiều bối cảnh khác. không lãng phí chọn các thuật toán tốt, suy nghĩ cho việc triển khai của bạn và sử dụng lại các triển khai đúng là tất cả các thành phần của thiết kế tốt; tất cả trong số đócải thiện khả năng đọc, khả năng bảo trì và tái sử dụng thường xuyên hơn là làm tổn thương nó.


0

Tôi cố gắng để làm cho mã có thể đọc được - hiệu suất bị nguyền rủa.

Khi nào, và nếu, mã chứng minh là quá chậm, tôi sẽ cấu trúc lại nó để nhanh hơn. Thông thường quá trình tái cấu trúc được theo sau với rất nhiều bình luận vì mã không có xu hướng dễ đọc hơn.


0

Ừm - Không bao giờ?

Nghiêm túc, mã phải luôn luôn được viết để dễ hiểu và duy trì.

Liên quan đến thời điểm xử lý các vấn đề về hiệu suất, hãy giải quyết chúng khi bạn xác định được chúng, không tối ưu hóa trước mã của bạn bởi vì sau đó bạn sẽ đoán được vấn đề về hiệu suất ở đâu.

Nếu mã của bạn được viết sao cho rõ ràng, ngắn gọn, dễ hiểu và có thể duy trì thì bạn hoặc một lập trình viên khác sẽ không gặp vấn đề gì trong việc tái cấu trúc mã để làm cho nó hiệu quả hơn.


3
Tôi không đồng ý với điều này. Yêu cầu về hiệu năng là một yêu cầu phi chức năng hợp lệ cho một hệ thống.
Thomas Owens

Về mặt kỹ thuật nếu có một yêu cầu liên quan đến hiệu suất được xác định rõ ràng thì có thể nói rằng bạn đã xác định được một vấn đề về hiệu suất và phải tính đến nó trong giải pháp của bạn. Những gì tôi đang nói là thông minh trước để bạn có thể tránh các vấn đề 'tiềm năng' không cụ thể.

Ah. Vâng, bạn hoàn toàn đúng trong trường hợp đó. Bạn không lo lắng về các khả năng bởi vì có rất nhiều, nhưng tập trung vào những gì bạn biết.
Thomas Owens

0

Tôi thường viết mã để có thể đọc được trước hết. Nếu, và chỉ khi, tôi thấy rằng chương trình chạy quá chậm để thực hiện công việc của nó, tôi có hồ sơ và tối ưu hóa. Điều đó nói rằng, không có gì sai khi tập thói quen thực hiện các tối ưu hóa phổ biến mà không ảnh hưởng đến khả năng đọc mã của bạn. Đó là, nếu một đoạn mã có thể được viết theo hai cách bằng nhau (hoặc gần như bằng nhau), hãy chọn một đoạn thường nhanh hơn.

Ví dụ, trong Python, khả năng hiểu danh sách (hoặc biểu thức trình tạo) có xu hướng nhanh hơn forvòng lặp tương đương , vì vậy tôi sử dụng cách hiểu danh sách nơi tôi có thể, nếu chúng không ảnh hưởng đến khả năng đọc (ví dụ: tôi không lồng vào danh sách hiểu Tôi có thể tránh nó và thay vào đó sử dụng một vòng lặp for vì việc hiểu danh sách lồng nhau có thể khó phân tích cú pháp tinh thần).

Tương tự, các kiểu dữ liệu bất biến có xu hướng nhanh hơn các kiểu dữ liệu có thể thay đổi, vì vậy tôi sử dụng các kiểu dữ liệu bất biến mà tôi có thể.


0

Nếu bạn đang làm việc trong các lĩnh vực thực sự quan trọng về hiệu suất, thì bạn không thể giảm hiệu quả như một cách suy nghĩ. Đó là một trong những điều quan trọng nhất cần suy nghĩ khi thiết kế sớm trong những trường hợp đó và theo những cách liên quan đến khả năng duy trì của kết quả cuối cùng.

Bạn không thể thiết kế và triển khai một máy chủ quy mô lớn và chỉ cần bắt đầu viết mã dễ dàng, có tài liệu tốt, chỉ sử dụng các chức năng chặn cho mọi thứ bằng khóa luồng toàn cầu, khóa toàn bộ hệ thống để xử lý từng yêu cầu của từng khách hàng trong khi không đặt bất kỳ suy nghĩ bất cứ điều gì vào trạng thái chia sẻ, tranh chấp chủ đề, và sự không điển hình. Đó là một công thức cho thảm họa và cần phải thiết kế lại và viết lại phần lớn mã được viết tài liệu độc đáo mà bạn đã viết theo những cách có thể dẫn đến mã hóa khó bảo trì nhất, bị vướng vào các điều kiện chủng tộc và bế tắc do cố gắng để đạt được hiệu quả cần thiết trong nhận thức muộn, trái ngược với việc chỉ nghĩ về các thiết kế làm việc hiệu quả, đơn giản, hiệu quả.

Một nhóm phát triển trò chơi 8 tháng được sản xuất với một công cụ chỉ đạt 2 khung hình mỗi giây trên phần cứng mạnh nhất của họ với 32 lõi trong khi có xu hướng bị đình trệ trong 15 giây mỗi khi màn hình bận rộn không thể ngay lập tức có được một sản phẩm có thể sử dụng được sửa một điểm nóng cục bộ. Rất có thể là thiết kế của họ là FUBAR theo cách đảm bảo việc xem lại sử thi của bảng vẽ và thay đổi thiết kế có thể xếp tầng vào mọi góc của cơ sở mã.

Với John Carmack, anh đã nói một lần về cách một bản demo công nghệ phải chạy ở mức tối thiểu hàng trăm đến hàng nghìn khung hình mỗi giây để tích hợp nó vào sản xuất. Đó không phải là một nỗi ám ảnh không lành mạnh với hiệu quả. Anh ta biết trước rằng các trò chơi cần phải chạy, toàn bộ, ở mức 30+ FPS để khách hàng thấy nó có thể chấp nhận được. Kết quả là một khía cạnh nhỏ như hệ thống bóng mềm không thể chạy ở tốc độ 30 FPS, nếu không thì toàn bộ trò chơi không thể đủ nhanh để cung cấp phản hồi thời gian thực cần thiết. Nó không sử dụng được cho đến khi đạt được hiệu quả cần thiết. Trong các lĩnh vực quan trọng về hiệu suất như vậy, nơi có yêu cầu cơ bản về hiệu quả, một giải pháp không đạt được tốc độ phù hợp thực sự không tốt hơn một giải pháp hoàn toàn không hoạt động,. Và bạn không thể thiết kế một hệ thống bóng mềm hiệu quả, chạy ở tốc độ hàng trăm đến hàng nghìn khung hình mỗi giây theo yêu cầu cho một công cụ trò chơi thời gian thực trừ khi bạn đặt một lượng lớn suy nghĩ vượt trội về hiệu quả của nó. Trên thực tế, trong những trường hợp như vậy, 90 +% công việc được định hướng xoay quanh hiệu quả vì việc tạo ra một hệ thống bóng mềm chỉ hoạt động tốt ở mức 2 giờ trên mỗi khung hình bằng cách sử dụng theo dõi đường dẫn, nhưng bạn không thể điều chỉnh nó để chạy ở hàng trăm khung hình mỗi giây mà không có sự thay đổi hoàn toàn khác nhau trong cách tiếp cận.

Khi hiệu quả là một phần cơ bản trong thiết kế của ứng dụng, bạn không thể mong đợi đạt được hiệu quả trong nhận thức muộn mà không mất nhiều thời gian hơn bạn đã tiết kiệm bằng cách bỏ qua nó, vì bạn không thể mong đợi đạt được một thiết kế hoạt động trong tầm nhìn xa. Không ai nói, "tôi không thể ngừng suy nghĩ về thiết kế cho đến sau này. Chỉ cần ghi lại mã của bạn và bạn có thể đưa ra một thiết kế phù hợp sau này ." Nhưng trong các kiến ​​trúc quan trọng về hiệu suất, đó là những gì bạn đang làm một cách hiệu quả nếu bạn không đặt nhiều sự quan tâm và suy nghĩ vào các thiết kế hiệu quả trước mắt.

Bây giờ điều đó không có nghĩa là bạn phải điều chỉnh các triển khai của mình ngay lập tức. Để biết chi tiết triển khai, có rất nhiều chỗ để lặp lại các giải pháp nhanh hơn sau khi đo lường với điều kiện là thiết kế sẽ không cần phải thay đổi và thường đó là cách hiệu quả nhất để thực hiện. Nhưng ở cấp độ thiết kế, điều đó có nghĩa là bạn phải suy nghĩ đầy đủ về cách thiết kế và kiến ​​trúc sẽ liên quan đến hiệu quả ngay từ đầu.

Sự khác biệt chính ở đây là thiết kế. Không dễ để thực hiện các thay đổi lớn đối với các thiết kế trong nhận thức muộn vì các thiết kế tích lũy phụ thuộc và các phụ thuộc sẽ bị phá vỡ nếu thiết kế thay đổi. Và nếu một thiết kế có yêu cầu phải hiệu quả hợp lý hoặc, trong một số trường hợp, chất lượng của nó phần lớn được đo bằng hiệu quả của nó, thì bạn không nên mong đợi có thể đạt được một thiết kế phù hợp như một suy nghĩ sau. Với bất kỳ sản phẩm cạnh tranh nào mà hiệu quả là một khía cạnh lớn về chất lượng cho dù đó là hệ điều hành hay trình biên dịch hoặc bộ xử lý video hay công cụ trò chơi hoặc công cụ vật lý, thì những suy nghĩ về hiệu quả và biểu diễn dữ liệu đã được suy nghĩ tỉ mỉ ngay từ đầu. Và trong những trường hợp đó, không phải là tối ưu hóa sớm để đặt quá nhiều suy nghĩ vào hiệu quả. Đó là đặt suy nghĩ chính xác vào thời điểm hiệu quả nhất để làm điều đó,

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.