Khi nào thì tốt hơn để tối ưu hóa một phần mềm để có hiệu suất tốt hơn, vào lúc bắt đầu hay khi kết thúc sự phát triển?


19

Tôi là một nhà phát triển phần mềm cơ sở và tôi đã tự hỏi khi nào sẽ là thời điểm tốt nhất để tối ưu hóa một phần mềm để có hiệu suất (tốc độ) tốt hơn.

Giả sử phần mềm không quá lớn và phức tạp để quản lý, tốt hơn là nên dành nhiều thời gian hơn để bắt đầu tối ưu hóa nó hay tôi chỉ nên phát triển phần mềm thực thi tất cả các chức năng một cách chính xác và sau đó tiến hành tối ưu hóa nó để có hiệu suất tốt hơn?


7
Thử nghiệm tư duy: Bạn chọn ngôn ngữ lập trình được diễn giải để phát triển trò chơi tương tác của mình và bạn khám phá được nửa chừng quá trình phát triển mà ngôn ngữ bạn chọn không có tốc độ cần thiết để đáp ứng yêu cầu tốc độ khung hình của bạn. Bạn có say sưa không?
Robert Harvey

8
Thử nghiệm suy nghĩ khác: Bạn cẩn thận tối ưu hóa một số mã trong trò chơi mà bạn cho là quan trọng đối với hiệu suất, nhưng sau đó bạn chạy một trình lược tả mã và phát hiện ra rằng mã bạn tối ưu hóa không thực sự đóng góp đáng kể vào hiệu suất tổng thể, và bạn đã giảm độ rõ của mã. Bạn đã lãng phí thời gian của bạn?
Robert Harvey

8
Hệ quả: Đó có phải là một hoặc / hoặc quyết định, hoặc có thể là quan trọng để sớm đưa ra một số quyết định thực hiện, trong khi trì hoãn những người khác?
Robert Harvey

1
Tôi đã gõ và xóa một câu trả lời và tiếp tục gõ lại nó. Không có câu trả lời nào cho câu hỏi này vì nó phụ thuộc. Trong một số trường hợp, việc gấp rút sản phẩm vượt qua tất cả các cân nhắc khác, trong một số trường hợp khác, tối ưu hóa ngay từ đầu là một yêu cầu khó khăn và hàng triệu kịch bản khác trong đó hợp lệ hoặc không tối ưu hóa, tối ưu hóa ngay từ đầu hoặc không tối ưu hóa tất cả và bất cứ điều gì khác
Pieter B

Không có vấn đề làm thế nào bạn nhìn vào nó. Lúc đầu, không có gì để tối ưu hóa vì không có gì để so sánh. Bạn vẫn cần 2 tài liệu tham khảo để tối ưu hóa một cái gì đó: hiệu suất lý tưởng (theo yêu cầu) và thực tế (cái bạn nhận được khi bạn có thứ gì đó chạy).
Laiv

Câu trả lời:


52

Điều số một nên luôn luôn và mãi mãi là dễ đọc. Nếu nó chậm nhưng có thể đọc được, tôi có thể sửa nó. Nếu nó bị hỏng nhưng có thể đọc được, tôi có thể sửa nó. Nếu nó không thể đọc được, tôi phải hỏi người khác điều này thậm chí phải làm gì.

Thật đáng chú ý làm thế nào hiệu suất mã của bạn có thể được khi bạn chỉ tập trung vào việc có thể đọc được. Vì vậy, tôi thường bỏ qua hiệu suất cho đến khi đưa ra một lý do để quan tâm. Điều đó không nên được hiểu là tôi không quan tâm đến tốc độ. Tôi làm. Tôi chỉ thấy rằng có rất ít vấn đề mà các giải pháp của họ thực sự nhanh hơn khi khó đọc.

Chỉ có hai điều đưa tôi ra khỏi chế độ này:

  1. Khi tôi nhìn thấy một cơ hội tại một cải tiến O lớn , thậm chí chỉ khi n đủ lớn mà bất cứ ai cũng quan tâm.
  2. Khi tôi có bài kiểm tra cho thấy vấn đề hiệu suất thực sự. Ngay cả với nhiều thập kỷ kinh nghiệm, tôi vẫn tin tưởng các bài kiểm tra hơn toán học của mình. Và tôi giỏi toán.

Trong mọi trường hợp, tránh tê liệt phân tích bằng cách khiến bản thân nghĩ rằng bạn không nên thử một giải pháp vì nó có thể không phải là nhanh nhất. Mã của bạn sẽ thực sự có lợi nếu bạn thử nhiều giải pháp vì thực hiện các thay đổi sẽ buộc bạn phải sử dụng một thiết kế giúp dễ dàng thay đổi. Một cơ sở mã linh hoạt có thể được thực hiện nhanh hơn sau này khi nó thực sự cần nó. Chọn linh hoạt theo tốc độ và bạn có thể chọn tốc độ bạn cần.


Tôi luôn thấy rằng các nhà phát triển phần mềm số một nên tập trung vào việc đưa sản phẩm lên kệ càng nhanh càng tốt với giao diện đẹp nhất có thể, các lỗi và thiết kế xấu có thể được sửa chữa sau này.
Pieter B

12
@PieterB: thật dễ dàng để làm chậm sự phát triển bởi một chiến lược như "lỗi và thiết kế xấu có thể được sửa chữa sau này" . Lưu ý, bởi thiết kế xấu, tôi có nghĩa là những thứ như mã không thể đọc được, phức tạp, cũng như mã bị áp đảo.
Doc Brown

5
@Walfrat: Tôi nghĩ rằng ví dụ của bạn có thể dễ dàng tăng tốc mà không mất khả năng đọc và tôi diễn giải câu trả lời này không phải là "mã có thể đọc được không có vấn đề về hiệu suất", nhưng giống như "các vấn đề về nước hoa sẽ không tự động tránh được bằng cách tạo mã không thể đọc được ".
Doc Brown

2
@PieterB: hoặc bạn có một khách hàng muốn lấy lại tiền của mình vì sản phẩm họ mua quá lỗi nên họ không thể sử dụng.
Doc Brown

2
@svidgen đánh giá tốc độ của mã không thể đọc được mà không cần kiểm tra là điều không thể. Tập trung vào tốc độ và bỏ qua khả năng đọc tạo ra các vấn đề tốc độ không thể nhận ra. Tập trung vào khả năng đọc làm cho vấn đề tốc độ trở nên rõ ràng, bạn sẽ không phải suy nghĩ về nó. Bạn sẽ thấy nó ngay khi bạn viết nó. Ngay cả khi bạn không, một khi bạn kiểm tra nó, ít nhất bạn sẽ có thể tìm ra vấn đề. Với tất cả điều này, tại sao mọi người nên tập trung mặc định vào tốc độ trên khả năng đọc? Tập trung vào tốc độ và bỏ qua khả năng đọc cho bạn cũng không.
candied_orange

27

Nếu một mức hiệu suất nhất định là cần thiết (một yêu cầu phi chức năng), thì đó phải là một mục tiêu thiết kế ngay từ đầu. Ví dụ, điều này có thể ảnh hưởng đến công nghệ nào có thể phù hợp hoặc cách bạn cấu trúc luồng dữ liệu trong chương trình.

Nhưng nói chung, không thể tối ưu hóa trước khi mã được viết: đầu tiên làm cho nó hoạt động, sau đó làm cho nó đúng, và cuối cùng, làm cho nó nhanh .

Một vấn đề lớn với việc tối ưu hóa trước khi thực hiện hầu hết các chức năng là bạn đã tự nhốt mình trong các quyết định thiết kế không tối ưu ở những vị trí sai. Thường có (nhưng không nhất thiết) một sự đánh đổi giữa khả năng bảo trì và hiệu suất. Hầu hết các phần của chương trình của bạn là hoàn toàn không liên quan đến hiệu suất! Các chương trình tiêu biểu chỉ có một vài điểm nóng thực sự đáng để tối ưu hóa. Vì vậy, hy sinh khả năng duy trì để thực hiện ở tất cả những nơi không cần hiệu suất là một giao dịch thực sự tồi tệ.

Tối ưu hóa cho khả năng bảo trì là cách tiếp cận tốt hơn. Nếu bạn dành sự thông minh của mình cho khả năng bảo trì và thiết kế rõ ràng, về lâu dài bạn sẽ dễ dàng xác định các phần quan trọng và tối ưu hóa chúng một cách an toàn mà không ảnh hưởng đến thiết kế tổng thể.


15

khi nào sẽ là thời điểm tốt nhất để tối ưu hóa một phần mềm để có hiệu suất (tốc độ) tốt hơn.

Bắt đầu bằng cách loại bỏ khỏi tâm trí của bạn khái niệm rằng hiệu suất là giống như tốc độ. Hiệu suất là những gì người dùng tin rằng hiệu suất là .

Nếu bạn làm cho một ứng dụng phản ứng nhanh gấp hai lần với một lần nhấp chuột và bạn đi từ mười micro giây đến năm micro giây, người dùng không quan tâm. Nếu bạn làm cho một ứng dụng phản ứng nhanh gấp hai lần với một lần nhấp chuột và bạn đi từ bốn nghìn năm đến hai nghìn năm, một lần nữa, người dùng không quan tâm.

Nếu bạn làm cho ứng dụng của mình nhanh gấp đôi và bạn sử dụng hết bộ nhớ trên máy và gặp sự cố, người dùng không quan tâm rằng giờ đây nó nhanh gấp đôi.

Hiệu suất là khoa học tạo ra sự đánh đổi hiệu quả về mức tiêu thụ tài nguyên để đạt được trải nghiệm người dùng cụ thể. Thời gian của người dùng là một tài nguyên quan trọng , nhưng nó không bao giờ chỉ là "nhanh hơn". Để đạt được các mục tiêu hiệu suất hầu như luôn đòi hỏi phải đánh đổi và họ thường đánh đổi thời gian để lấy không gian hoặc ngược lại.

Giả sử phần mềm không quá lớn và phức tạp để quản lý

Đó là một giả định khủng khiếp.

Nếu phần mềm không lớn và phức tạp để quản lý thì có lẽ nó không giải quyết được một vấn đề thú vị mà người dùng quan tâm và có lẽ nó rất dễ tối ưu hóa.

tốt hơn là nên dành nhiều thời gian hơn khi bắt đầu tối ưu hóa nó hay tôi chỉ nên phát triển phần mềm thực thi tất cả các chức năng một cách chính xác và sau đó tiến hành tối ưu hóa nó để có hiệu suất tốt hơn?

Bạn đang ngồi ở một trang trống và bạn viết void main() {}Bạn có bắt đầu tối ưu hóa không? Không có gì để tối ưu hóa! Thứ tự đúng là:

  • Làm cho nó biên dịch
  • Làm cho nó đúng
  • Làm cho nó thanh lịch
  • Làm nhanh

Nếu bạn cố gắng thực hiện theo bất kỳ thứ tự nào khác, bạn sẽ kết thúc với mã sai là một mớ hỗn độn, và bây giờ bạn đã có một chương trình tạo ra câu trả lời sai thực sự nhanh chóng và chống lại sự thay đổi.

Nhưng có một bước bị thiếu ở đó. Thứ tự đúng thực sự là:

  • Làm việc với khách hàng và quản lý để thiết lập các số liệu và mục tiêu hiệu suất thực tế, có thể đo lường được, hãy nhớ rằng tốc độ không phải là chỉ số duy nhất mà khách hàng quan tâm.
  • Triển khai khai thác thử nghiệm có thể theo dõi trạng thái hiện tại của dự án so với mục tiêu của bạn
  • Làm cho nó biên dịch
  • Chạy thử nghiệm. Nếu bạn không còn trong mục tiêu của mình, hãy nhận ra rằng bạn có thể đã đi vào một con đường xấu sớm. Sử dụng khoa học . Bạn đã giới thiệu một thuật toán xấu có thể được sửa chữa, hoặc là một cái gì đó sai về cơ bản? Nếu nó sai về cơ bản, thì hãy bắt đầu lại. Nếu nó có thể được sửa, hãy nhập một lỗi và quay lại sau.
  • Làm cho nó đúng
  • Chạy thử nghiệm lại ...
  • Làm cho nó thanh lịch
  • Chạy thử nghiệm lại ...
  • Bạn có tuân thủ mục tiêu của bạn? Nếu có, hãy đến bãi biển . Nếu không, làm cho nó đủ nhanh .

"Hiệu suất là những gì người dùng tin rằng hiệu suất là." - thực sự, đôi khi kinh nghiệm người dùng thực sự là tốt hơn khi điều chúng ta mong đợi để mất thời gian làm thời gian mất: webdesignerdepot.com/2017/09/when-slower-ux-is-better-ux
svidgen

có thể "khoa học" hơn là "sử dụng khoa học" :)
màu xanh

@svidgen: Tôi nhớ một lần thay đổi mã của mình để làm chậm thanh tiến trình. Người dùng có ấn tượng rằng một số công việc thực sự đã được thực hiện và hài lòng với điều đó. Hàm được tính toán rất hữu ích nhưng có vẻ như chương trình không làm gì cả nếu kết quả ở đó sau một phần mười giây.
Giorgio

2
@Giorgio: Điều này hẹn hò với tôi, nhưng tôi nhớ khi lần đầu tiên tôi có một ổ đĩa cứng, và tôi đã lưu một trò chơi hoặc một tài liệu và nghĩ rằng đã xảy ra sự cố vì thao tác không mất thời gian có thể nhận thấy so với lưu vào đĩa mềm. Và tất nhiên bây giờ trạng thái trò chơi và tài liệu quá lớn để chúng tôi quay lại tiết kiệm thời gian.
Eric Lippert

3

Theo nguyên tắc chung, tốt nhất là tối ưu hóa hiệu suất sau này, nhưng tôi đã thấy nhiều dự án trở nên tồi tệ khi các nhà phát triển nhận ra rằng họ đã kết thúc với phần mềm sẽ chậm khi tải bất kỳ tải hoặc dữ liệu quan trọng nào vào đó.

Vì vậy, một cách tiếp cận trung gian sẽ là tốt nhất theo ý kiến ​​của tôi; đừng quá chú trọng vào nó, nhưng đừng coi thường hiệu suất.

Tôi sẽ đưa ra một ví dụ mà tôi đã thấy nhiều lần; được cung cấp thư viện ORM, chúng tôi có một thực thể Người dùng có thể có một hoặc nhiều Đơn hàng. Hãy lặp lại tất cả các Đơn đặt hàng cho Người dùng và tìm hiểu xem Người dùng đã chi bao nhiêu trong cửa hàng của chúng tôi - một cách tiếp cận ngây thơ:

User user = getUser();
int totalAmount;
for (Order o : user.getOrders()) {
  totalAmount += o.getTotalAmount();
} 

Tôi đã thấy các nhà phát triển viết những điều tương tự, mà không có bất kỳ suy nghĩ về ý nghĩa; đầu tiên chúng tôi có được người dùng, hy vọng sẽ chỉ là một truy vấn SQL trên bảng Người dùng (nhưng có thể liên quan đến nhiều, nhiều hơn nữa), sau đó chúng tôi lặp qua các đơn đặt hàng, có thể bao gồm nhận tất cả dữ liệu có liên quan cho tất cả các dòng đơn hàng theo thứ tự , thông tin sản phẩm, v.v. - tất cả điều này chỉ để có được một số nguyên cho mỗi đơn hàng!

Số lượng truy vấn SQL ở đây có thể làm bạn ngạc nhiên. Tất nhiên, nó phụ thuộc vào cách các thực thể của bạn được cấu trúc.

Ở đây, cách tiếp cận đúng rất có thể là thêm một hàm riêng để lấy tổng từ cơ sở dữ liệu thông qua một truy vấn riêng được viết bằng ngôn ngữ truy vấn do ORM cung cấp và tôi sẽ ủng hộ việc này lần đầu tiên và không hoãn điều này cho sau này; bởi vì nếu bạn làm thế, có lẽ bạn sẽ phải giải quyết nhiều vấn đề hơn và không biết bắt đầu từ đâu.


3

Tổng hiệu năng hệ thống là một sản phẩm của các tương tác phức tạp về tổng số các thành phần hệ thống. Đó là một hệ phi tuyến. Do đó, hiệu suất sẽ được kiểm soát không chỉ bởi hiệu suất riêng lẻ của các thành phần mà còn bởi các nút thắt giữa chúng.

Rõ ràng là bạn không thể kiểm tra các tắc nghẽn nếu tất cả các thành phần trong hệ thống của bạn chưa được xây dựng, vì vậy bạn thực sự không thể kiểm tra rất sớm. Mặt khác, sau khi hệ thống được xây dựng, bạn có thể không thấy dễ dàng thực hiện các thay đổi bạn cần thực hiện để có được hiệu suất bạn muốn. Vì vậy, đây là một fide xương xương Catch-22 .

Để làm cho vấn đề khó khăn hơn, hồ sơ hiệu suất của bạn có thể thay đổi mạnh mẽ khi bạn chuyển sang môi trường giống như sản xuất, thường không có sẵn sớm.

Vậy bạn làm gì? Vâng, một vài điều.

  1. Hãy thực dụng. Ngay từ sớm, bạn có thể chọn sử dụng các tính năng nền tảng là "thực tiễn tốt nhất" cho hiệu suất; ví dụ: sử dụng nhóm kết nối, giao dịch không đồng bộ và tránh trạng thái, có thể là cái chết của ứng dụng đa luồng trong đó các công nhân khác nhau đang có quyền truy cập vào dữ liệu được chia sẻ. Thông thường, bạn sẽ không kiểm tra các mẫu này để biết hiệu suất, bạn chỉ cần biết từ kinh nghiệm những gì hoạt động tốt.

  2. Hãy lặp đi lặp lại. Thực hiện các biện pháp hiệu suất cơ bản khi hệ thống còn khá mới và thỉnh thoảng kiểm tra lại để đảm bảo mã mới được giới thiệu không làm giảm hiệu suất quá nhiều.

  3. Đừng quá tối đa sớm. Bạn không bao giờ biết điều gì sẽ quan trọng và điều gì sẽ không quan trọng; một thuật toán phân tích chuỗi siêu nhanh có thể không giúp ích gì nếu chương trình của bạn liên tục chờ vào I / O, chẳng hạn.

  4. Trong các ứng dụng web đặc biệt, bạn có thể không tập trung quá nhiều vào hiệu suất mà là khả năng mở rộng. Nếu ứng dụng có thể mở rộng ra, hiệu suất gần như không thành vấn đề, vì bạn có thể tiếp tục thêm các nút vào trang trại của mình cho đến khi đủ nhanh.

  5. Đặc biệt chú ý đến cơ sở dữ liệu. Do các ràng buộc toàn vẹn giao dịch, cơ sở dữ liệu có xu hướng là một nút cổ chai chi phối mọi bộ phận của hệ thống. Nếu bạn cần một hệ thống hiệu năng cao, hãy đảm bảo rằng bạn có những người tài năng làm việc về phía cơ sở dữ liệu, xem xét các kế hoạch truy vấn và phát triển các cấu trúc bảng và chỉ mục sẽ giúp các hoạt động chung hiệu quả nhất có thể.

Hầu hết các hoạt động này không dành cho sự khởi đầu hoặc kết thúc của dự án mà phải được tham dự liên tục .


1

Tôi là một nhà phát triển phần mềm cơ sở và tôi đã tự hỏi khi nào sẽ là thời điểm tốt nhất để tối ưu hóa một phần mềm để có hiệu suất (tốc độ) tốt hơn.

Hiểu rằng có 2 thái cực rất khác nhau.

Cực đoan đầu tiên là những thứ ảnh hưởng đến một phần lớn của thiết kế, như làm thế nào để phân chia công việc thành bao nhiêu tiến trình và / hoặc luồng và cách các phần giao tiếp (ổ cắm TCP / IP? Gọi chức năng trực tiếp?), Liệu có thực hiện JIT nâng cao không hoặc một trình thông dịch "một opcode tại một thời điểm", hoặc có nên lập kế hoạch cấu trúc dữ liệu để có thể tuân theo SIMD hay ... Những điều này có xu hướng ảnh hưởng mạnh mẽ đến việc triển khai và trở nên quá khó / tốn kém để phù hợp với retro.

Một thái cực khác là tối ưu hóa vi mô - những điều chỉnh nhỏ bé ở khắp mọi nơi. Những điều này có xu hướng hầu như không ảnh hưởng đến việc triển khai (và thường được trình biên dịch thực hiện tốt nhất) và thật đơn giản để thực hiện những tối ưu này bất cứ khi nào bạn cảm thấy thích.

Ở giữa những thái cực này là một khu vực màu xám khổng lồ.

Những gì nó thực sự đi xuống là kinh nghiệm / phỏng đoán có giáo dục đang được sử dụng để trả lời một câu hỏi "làm lợi ích biện minh cho chi phí". Để tối ưu hóa ở mức / gần một cực trị nếu bạn đoán sai thường xuyên, điều đó có nghĩa là vứt bỏ tất cả công việc của bạn và khởi động lại từ đầu hoặc thất bại dự án (dành quá nhiều thời gian cho một thiết kế quá phức tạp không cần thiết). Ở / gần cực khác, việc rời khỏi nó cho đến khi bạn có thể chứng minh vấn đề đó bằng cách sử dụng phép đo (ví dụ như hồ sơ) là điều hợp lý hơn nhiều.

Thật không may, chúng ta đang sống trong một thế giới nơi có quá nhiều người nghĩ rằng tối ưu hóa chỉ bao gồm những thứ (hầu hết không liên quan) ở mức độ "tầm thường".


1

Dễ dàng nhất để viết mã không phải là porformant hay duy trì. Viết mã porformant khó hơn. Nó khó hơn để viết mã duy trì. Và nó là khó khăn nhất để viết mã vừa có thể duy trì và thực hiện.

Nhưng, làm cho trình diễn mã có thể duy trì dễ dàng hơn so với làm cho mã trình diễn có thể duy trì được.

Bây giờ, rõ ràng, nó phụ thuộc vào loại hệ thống bạn đang thực hiện, một số hệ thống sẽ có hiệu suất rất quan trọng và cần được lên kế hoạch ngay từ đầu. Đối với những người cực kỳ tài năng như Eric Lippert, người đã trả lời ở trên, những hệ thống này có thể là phổ biến; nhưng đối với hầu hết chúng ta, họ là thiểu số trong các hệ thống chúng ta xây dựng.

Tuy nhiên, với tình trạng phần cứng hiện đại, trong phần lớn các hệ thống, không cần phải đặc biệt chú ý đến tối ưu hóa ngay từ đầu, mà thay vào đó, tránh phá hủy hiệu năng thường là đủ. Điều tôi muốn nói là, tránh làm những việc ngu ngốc đơn giản như mang lại tất cả các bản ghi của bảng để lấy số đếm thay vì chỉ truy vấn select count(*) from table. Chỉ cần tránh phạm sai lầm và nỗ lực để hiểu các công cụ bạn đang sử dụng.

Tiếp theo, đầu tiên tập trung vào làm cho mã của bạn có thể duy trì. Ý tôi là:

  1. Phân tách mối quan tâm nghiêm ngặt nhất có thể (ví dụ: không trộn lẫn quyền truy cập dữ liệu với logic nghiệp vụ)
  2. Tham khảo các loại trừu tượng thay vì các loại cụ thể nếu có thể
  3. Làm cho mã của bạn có thể kiểm tra

Mã duy trì dễ dàng hơn nhiều để tối ưu hóa khi số liệu thống kê cho thấy nó là cần thiết.

Tiếp theo, hãy đảm bảo mã của bạn có RẤT NHIỀU bài kiểm tra tự động, điều này có một số lợi ích. Ít lỗi hơn có nghĩa là nhiều thời gian hơn để tối ưu hóa, khi cần thiết . Ngoài ra, khi bạn tối ưu hóa, bạn có thể lặp lại và tìm giải pháp tốt nhất nhanh hơn nhiều vì bạn thấy các lỗi trong triển khai của mình nhanh hơn nhiều.

Các kịch bản triển khai tự động và cơ sở hạ tầng theo kịch bản cũng rất hữu ích để điều chỉnh hiệu suất, vì một lần nữa, chúng cho phép bạn lặp lại nhanh hơn; không đề cập đến lợi ích khác của nó.

Vì vậy, như mọi khi, có những trường hợp ngoại lệ (mà bạn sẽ cần kinh nghiệm để xác định rõ hơn), nhưng, nói chung, lời khuyên của tôi là: Đầu tiên, tìm hiểu các công cụ của bạn và tránh tắc nghẽn hiệu suất mã hóa. Thứ hai, đảm bảo mã của bạn có thể duy trì. Thứ ba, kiểm tra tự động. Thứ tư, triển khai hoàn toàn tự động. Chỉ sau khi những điều này được thực hiện, bạn nên lo lắng về tối ưu hóa.


1

Tôi có thể bị thiên vị khi làm việc trong các lĩnh vực rất quan trọng về hiệu suất như xử lý hình ảnh và raytracing, nhưng tôi vẫn nói để tối ưu hóa "càng muộn càng tốt" . Cho dù các yêu cầu của bạn có hiệu suất quan trọng đến mức nào, luôn có nhiều thông tin và sự rõ ràng hơn sau khi bạn đo lường, hơn là trước, điều đó có nghĩa là ngay cả những tối ưu hóa hiệu quả nhất thường được áp dụng sau khi có được kiến ​​thức như vậy.

Trường hợp đặc biệt

Nhưng đôi khi "càng muộn càng tốt" vẫn còn khá sớm trong một số trường hợp đặc biệt. Ví dụ, nếu chúng ta đang nói về trình kết xuất ngoại tuyến, các cấu trúc dữ liệu và kỹ thuật bạn sử dụng để đạt được hiệu suất thực sự thấm vào thiết kế cuối của người dùng. Điều này nghe có vẻ kinh tởm nhưng lĩnh vực này rất tiên tiến và quan trọng về hiệu năng đến mức người dùng chấp nhận các điều khiển kết thúc của người dùng cụ thể cho các kỹ thuật tối ưu hóa áp dụng cho một raytracer cụ thể (ví dụ: bộ nhớ đệm chiếu xạ hoặc ánh xạ photon), vì một số trong số chúng được sử dụng chờ hàng giờ để một hình ảnh được hiển thị và những người khác được sử dụng để bỏ ra số tiền khổng lồ để thuê hoặc sở hữu một trang trại kết xuất với các máy dành riêng để kết xuất. Có sự giảm đáng kể về thời gian và tiền bạc cho những người dùng đó nếu trình kết xuất ngoại tuyến cạnh tranh có thể cung cấp một mức giảm không đáng kể về thời gian kết xuất. Đây là một lĩnh vực mà thời gian giảm 5% thực sự kích thích người dùng.

Trong những trường hợp đặc biệt như vậy, bạn không thể chỉ chọn một kỹ thuật kết xuất willy-nilly và hy vọng sẽ tối ưu hóa nó sau này, vì toàn bộ thiết kế, bao gồm cả thiết kế cuối người dùng, xoay quanh cấu trúc dữ liệu và thuật toán bạn sử dụng. Bạn thậm chí không thể chỉ đi với những gì làm việc tốt cho người khác kể từ đây, với tư cách cá nhân, điểm mạnh và điểm yếu cụ thể của bạn, là yếu tố quyết định rất lớn để đưa ra giải pháp cạnh tranh. Tư duy và sự nhạy cảm của nhà phát triển chính đằng sau Arnold khác với những người làm việc trên VRay, người đã sử dụng một cách tiếp cận rất khác; họ không nhất thiết phải trao đổi địa điểm / kỹ thuật và thực hiện công việc tốt nhất (mặc dù cả hai đều là nhà lãnh đạo công nghiệp). Bạn phải loại thử nghiệm và nguyên mẫu và điểm chuẩn và tìm thấy những gì bạn ' đặc biệt giỏi trong việc đưa ra vô số các kỹ thuật tiên tiến ngoài kia nếu bạn hy vọng sẽ bán được thứ gì đó cạnh tranh sẽ thực sự bán được. Vì vậy, trong trường hợp đặc biệt này, mối quan tâm về hiệu suất di chuyển lên phía trước vì có lẽ là mối quan tâm quan trọng nhất trước khi bắt đầu phát triển.

Tuy nhiên, điều đó không nhất thiết là vi phạm tối ưu hóa "càng muộn càng tốt" , đó chỉ là "càng muộn càng tốt" là khá sớm trong những trường hợp cực đoan và kỳ dị này. Tìm ra khi nào và cả những gì không cần mối quan tâm hiệu năng sớm như vậy, nếu có, có lẽ là thách thức chính đối với nhà phát triển. Những gì không tối ưu hóa có thể là một trong những điều quý giá nhất để học và tiếp tục học hỏi trong sự nghiệp của nhà phát triển, vì bạn không thể thiếu những nhà phát triển ngây thơ muốn tối ưu hóa mọi thứ (và thật không may, ngay cả một số cựu chiến binh đã cố gắng giữ công việc của họ bằng cách nào đó mặc dù năng suất phản tác dụng của họ).

Muộn nhất có thể

Có lẽ phần khó nhất là cố gắng hiểu ý nghĩa của nó. Tôi vẫn đang học và tôi đã lập trình được gần ba thập kỷ. Nhưng đặc biệt là bây giờ trong thập kỷ thứ ba của tôi, tôi bắt đầu nhận ra điều đó không khó. Đó không phải là khoa học tên lửa, nếu bạn tập trung vào thiết kế hơn là thực hiện. Thiết kế của bạn càng rời khỏi phòng thở để tối ưu hóa phù hợp sau này mà không thay đổi thiết kế, bạn càng có thể tối ưu hóa sau này. Và càng ngày càng tăng năng suất tôi đã tìm kiếm những thiết kế như vậy đủ khả năng cho tôi phòng thở đó.

Thiết kế cung cấp phòng thở để tối ưu hóa sau này

Những kiểu thiết kế này thực sự không khó đạt được trong hầu hết các trường hợp nếu chúng ta có thể áp dụng một số "lẽ thường". Như một câu chuyện cá nhân, tôi thích nghệ thuật thị giác như một sở thích (tôi thấy phần nào giúp lập trình phần mềm cho các nghệ sĩ tự mình hiểu được nhu cầu của họ và nói ngôn ngữ của họ), và tôi đã dành thời gian vào đầu những năm 2000 bằng cách sử dụng các ứng dụng Oekaki trực tuyến như một cách nhanh chóng để vẽ nguệch ngoạc và chia sẻ công việc của tôi và kết nối với các nghệ sĩ khác.

Đặc biệt là trang web và applet yêu thích của tôi đã bị đánh lừa với các lỗi hiệu suất (bất kỳ kích thước bàn chải không tầm thường nào cũng sẽ chậm khi thu thập dữ liệu), nhưng có một cộng đồng rất tốt. Để giải quyết các vấn đề về hiệu suất, tôi đã sử dụng các cọ 1 hoặc 2 pixel nhỏ xíu và chỉ viết nguệch ngoạc công việc của mình như vậy:

nhập mô tả hình ảnh ở đây

Trong khi đó, tôi tiếp tục đưa ra cho tác giả các đề xuất phần mềm để cải thiện hiệu suất và anh ấy nhận thấy các đề xuất của tôi có bản chất kỹ thuật đặc biệt nói về tối ưu hóa bộ nhớ và thuật toán, v.v. Vì vậy, anh ấy thực sự hỏi tôi có phải là lập trình viên không và tôi nói có và anh ấy mời tôi làm việc về mã nguồn.

Vì vậy, tôi đã xem mã nguồn, chạy nó, lập hồ sơ và kinh hoàng là anh ấy đã thiết kế phần mềm xung quanh khái niệm "giao diện pixel trừu tượng", giống như IPixel, cuối cùng là nguyên nhân sâu xa đằng sau các điểm nóng hàng đầu cho mọi thứ năng động phân bổ và gửi cho mỗi pixel của mỗi hình ảnh. Tuy nhiên, không có cách nào thực tế để tối ưu hóa điều đó mà không xem xét lại toàn bộ thiết kế của phần mềm bởi vì thiết kế đã nhốt anh ta vào một góc mà không vượt quá tầm tối ưu vi mô tầm thường nhất khi các bản tóm tắt của chúng tôi hoạt động ở mức độ chi tiết của một pixel trừu tượng duy nhất và mọi thứ phụ thuộc vào pixel trừu tượng này.

Tôi nghĩ đó là vi phạm "lẽ thường" nhưng rõ ràng đó không phải là lẽ thường đối với nhà phát triển. Nhưng nó giống như không phải là những thứ trừu tượng ở mức độ chi tiết như vậy, trong đó ngay cả những trường hợp sử dụng cơ bản nhất cũng sẽ được tạo ra bởi hàng triệu người, như với pixel, hoặc hạt hoặc đơn vị nhỏ trong mô phỏng quân đội ginormous. Ưu tiên cho IImage(bạn có thể xử lý tất cả các định dạng hình ảnh / pixel bạn cần tại mà cồng kềnh mức tổng hợp) hoặc IParticleSystemđến IPixelhoặc IParticle, và sau đó bạn có thể đưa vào cơ bản nhất và nhanh chóng-to-ghi và đơn giản hiểu hiện thực đằng sau giao diện như vậy và có tất cả các phòng thở bạn sẽ cần phải tối ưu hóa sau này mà không cần xem xét lại toàn bộ thiết kế của phần mềm.

Và đó là mục tiêu như tôi thấy ngày nay. Không bao gồm các trường hợp đặc biệt như trình kết xuất ngoại tuyến ở trên, thiết kế có đủ phòng thở để tối ưu hóa càng muộn càng tốt, với càng nhiều thông tin nhận thức càng tốt (bao gồm các phép đo) và áp dụng bất kỳ tối ưu hóa cần thiết nào càng muộn càng tốt.

Tất nhiên, tôi không nhất thiết phải đề xuất bắt đầu sử dụng thuật toán phức tạp bậc hai trên các đầu vào dễ dàng đạt đến kích thước không tầm thường trong các trường hợp kết thúc người dùng thông thường. Ai làm điều đó? Nhưng tôi thậm chí không nghĩ rằng đó là một vấn đề lớn như vậy nếu việc thực hiện dễ dàng trao đổi sau này. Đó vẫn không phải là một sai lầm nghiêm trọng nếu bạn không phải xem xét lại bất kỳ thiết kế nào.


0

Nó phụ thuộc vào hiệu suất đó có nghĩa gì với ứng dụng của bạn. Và về việc thậm chí có thể tối ưu hóa hiệu suất trước khi ứng dụng của bạn hoàn tất chức năng hay không.

Thông thường bạn không nên lo lắng về điều đó cho đến khi bạn không có gì để làm tốt hơn, nhưng có thể là một mức hiệu suất nhất định rất quan trọng đối với sự thành công của ứng dụng của bạn. Nếu đó là trường hợp và bạn nghi ngờ nó có thể không dễ dàng, bạn nên bắt đầu xem hiệu suất vì "thất bại nhanh".

Một nguyên tắc quan trọng cho bất kỳ dự án là tập trung vào các phần cứng đầu tiên. Bằng cách đó, nếu hóa ra bạn không thể làm điều đó, bạn sẽ biết sớm và sẽ có thời gian để thử một cái gì đó hoàn toàn khác hoặc dự án có thể bị hủy trước khi chi quá nhiều cho nó.


0

Tôi sẽ đề nghị hiệu suất là nhiều hơn tốc độ. Nó bao gồm quy mô (hàng trăm đến hàng ngàn người dùng đồng thời). Để chắc chắn rằng bạn không muốn ứng dụng tăng khi nó tải sản xuất. Hiệu năng bao gồm bao nhiêu tài nguyên (ví dụ bộ nhớ) mà ứng dụng tiêu thụ.

Hiệu suất cũng dễ sử dụng. Một số người dùng thà có 1 lần nhấn phím thực hiện một tác vụ trong 10 giây hơn là 2 lần nhấn phím thực hiện nhiệm vụ trong 1 giây. Đối với những thứ như thế yêu cầu thiết kế dẫn của bạn. Tôi không muốn đưa những thứ như thế này cho người dùng sớm. Trong chân không họ có thể nói X nhưng một khi họ đang làm việc với một bản phát hành trước chức năng, họ có thể nói Y.

Tốc độ cá nhân tốt nhất là giữ một tài nguyên như kết nối cơ sở dữ liệu. Nhưng đối với quy mô, bạn nên có được kết nối càng muộn càng tốt và giải phóng nó càng sớm càng tốt. Một chuyến đi đến cơ sở dữ liệu để có được 3 thứ nhanh hơn 3 chuyến đi đến cơ sở dữ liệu.

Bạn đang thực hiện một chuyến đi cho thông tin không thay đổi trong phiên. Nếu vậy hãy lấy nó tại phiên bắt đầu và giữ nó là bộ nhớ.

Khi chọn loại bộ sưu tập hãy xem xét chức năng, tốc độ và kích thước.

Bạn có chắc chắn cần phải giữ các mục trong một bộ sưu tập? Một vấn đề phổ biến là đọc tất cả các dòng từ một tệp vào danh sách và sau đó xử lý danh sách từng dòng một. Sẽ hiệu quả hơn nhiều khi đọc từng dòng một tệp và bỏ qua danh sách.

Bạn có lặp lại ba lần khi bạn có thể lặp một lần và làm ba việc.

Có một nơi mà bạn có thể cần phải xử lý trên một chủ đề khác với một cuộc gọi lại. Nếu vậy gói mã với nhu cầu có thể có trong tâm trí nếu nó không can thiệp vào nhu cầu thiết kế ngay lập tức.

Rất nhiều hiệu suất cũng là mã sạch.

Có tối ưu hóa sớm và chỉ có những công việc thông thường ở phía trước mà không thực sự mất nhiều thời gian hơn.

Trong cơ sở dữ liệu là nơi tôi thấy tối ưu hóa sớm. Sẽ không bình thường hóa tốc độ trước khi có vấn đề về tốc độ. Đối số tôi nhận được là nếu chúng ta thay đổi bảng sau đó thì chúng ta phải thay đổi mọi thứ. Thường thì bạn có thể tạo một khung nhìn trình bày dữ liệu theo cách đó và nó có thể cần được hoán đổi cho một bảng không chuẩn hóa sau này.

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.