Làm cách nào để tránh Trực giác Tối ưu hóa xấu của Nhà phát triển trực tuyến?


22

Tôi thấy trên một bài báo đưa ra tuyên bố này:

Các nhà phát triển thích tối ưu hóa mã và với lý do tốt. Thật là thỏa mãn và vui vẻ. Nhưng biết khi nào để tối ưu hóa là quan trọng hơn nhiều. Thật không may, các nhà phát triển thường có trực giác khủng khiếp về vấn đề hiệu năng trong ứng dụng sẽ thực sự ở đâu.

Làm thế nào một nhà phát triển có thể tránh được trực giác xấu này? Có các công cụ tốt để tìm phần nào trong mã của bạn thực sự cần tối ưu hóa (cho Java) không? Bạn có biết một số bài viết, lời khuyên, hoặc đọc tốt về chủ đề này?


1
Điều này dẫn đến "Làm thế nào để tôi tránh [dựa vào] trực giác [khi đưa ra quyết định]?" Đơn giản: bạn xác minh với dữ liệu cứng và dữ liệu. Vì vậy, trong trường hợp tối ưu hóa, từ quan điểm của nhà phát triển: điểm chuẩn của bạn.
haylem

Câu trả lời:


44
  • Sử dụng một hồ sơ tốt để xác định các phương pháp đắt tiền.
  • Tài liệu bao lâu các điểm nóng thực sự mất.
  • Viết một triển khai nhanh hơn các điểm nóng
  • Tài liệu các điểm nóng bây giờ mất bao lâu, hy vọng không làm cho chúng trở thành điểm nóng nữa.

Về cơ bản, bạn cần có khả năng chứng minh cho người khác biết vấn đề đang ở đâu và sự thay đổi này đã khiến nó biến mất.

Không thể chứng minh sự cải tiến, đủ điều kiện - theo ý kiến ​​cá nhân của tôi - để quay lại ngay phiên bản gốc.


51
Hoặc nói một cách đơn giản hơn: "Để tránh trực giác tối ưu hóa xấu, đừng sử dụng trực giác. Đo lường."
Kyralessa

6
Đó là lý do tại sao của bạn là một câu trả lời và của tôi chỉ là một nhận xét. : P
Kyralessa

2
@Thomas, nếu bạn quan tâm đến khả năng đọc và khả năng bảo trì, bạn không nhìn chính xác vào các vấn đề về hiệu suất, phải không?

3
@Thomas, tôi không đồng ý. Ngay cả trong spec, bạn cần kiểm tra lại mã mới một cách kỹ lưỡng. Điều này là không cần thiết cho mã cũ. Hoàn nguyên.

2
@ Thorbjørn Sau khi điều chỉnh hiệu suất, bạn cũng cần kiểm tra lại mã mới một cách kỹ lưỡng. Tiết kiệm thời gian hoặc bộ nhớ là vô nghĩa nếu bạn giới thiệu một khiếm khuyết.
Thomas Owens

10

Cách duy nhất để biết nơi tối ưu hóa là hồ sơ mã của bạn. Thay vì thực hiện các thay đổi mà bạn nghĩ sẽ mang lại lợi ích, hãy biết chắc chắn mã hiệu suất kém nhất ở đâu và bắt đầu từ đó.

Java làm điều này khá dễ dàng với công cụ VisualVM , được gói cùng với các bản phát hành gần đây của Bộ công cụ phát triển Java (JDK). Ý tưởng là tìm ra phương thức nào được gọi là nhiều nhất và phương thức nào bạn dành phần lớn thời gian của mình, cả trong mã của bạn và trong các thư viện bên ngoài. Bạn cũng có thể nhận dữ liệu hiệu suất trên bộ sưu tập rác để bạn có thể điều chỉnh trình thu thập của mình và điều chỉnh không gian heap tối thiểu / tối đa theo yêu cầu của ứng dụng.


VisualVM không có trong JRE, chỉ có JDK.

1
@ Thorbjørn Ravn Andersen Cuộc gọi tốt. Tôi nên làm rõ. Tuy nhiên, nếu bạn đang thực hiện phát triển Java, bạn thường cài đặt JDK (mặc dù bạn có thể đang chạy OpenJDK hoặc tương tự - Tôi không biết liệu chúng có đi kèm với VisualVM không).
Thomas Owens

1
Tôi rất thường xuyên chuyển đổi các không gian làm việc trong Eclipse, sau đó mặc định là JRE đã khởi chạy Eclipse. Vì việc cài đặt JRE dễ dàng hơn nhiều so với JDK, chúng tôi đã dần dần chuyển sang quy trình xây dựng kiến ​​bao gồm trình biên dịch Eclipse và do đó có thể chạy trên JRE đơn giản. Do đó, những ngày này bạn thực sự có thể làm việc thực sự mà không cần JDK. VisualVM có thể được tải xuống một cách riêng biệt làm cho nó dễ sử dụng hơn với một phiên bản Java đã cho, vì trong JVM của Windows 64 bit không thể kết nối với JVM 32 bit và ngược lại.

9

Như bất cứ ai ở đây đang nói về hồ sơ, tôi sẽ tập trung vào phần này của câu hỏi.

Làm thế nào một nhà phát triển có thể tránh được trực giác xấu này?

Bạn. làm không phải. Thay vào đó bạn không bao giờ tối ưu hóa sớm .
Lặp lại nó nhiều lần và một lần nữa, vì đó là một câu thần chú tôn giáo.

Bạn sẽ thấy mình làm điều đó và sẽ phát hiện ra bạn không nên.
Và sau đó một lần nữa.
Và một lần nữa.

Tối ưu hóa sớm là một trong những tội lỗi vốn của lập trình viên .

Các công cụ và công cụ là một phần của việc tối ưu hóa sau này là một thủ công đã được thiết lập .


Chắc chắn sớm tối ưu hóa "mã phức tạp". Các thuật toán và / hoặc cấu trúc dữ liệu phù hợp với vấn đề của bạn và (với tải xử lý dự kiến ​​của bạn) có các đặc tính hiệu suất tốt là điều cần được thực hiện trước khi bạn bắt đầu viết mã.
Vatine

@Vatine Vâng, đã ở đó. Không, đừng. Làm những gì phù hợp với bản đồ tư duy của bạn về vấn đề trong tay. Nó có thểthuật toán hiệu quả nhất và tôi muốn bạn, nó không phải như vậy.
ZJR

Nó nghe có vẻ như là nguyên tắc của YAGNI - Bạn không phải là người cần nó!
EL Yusubov

7

Những công cụ này được gọi là hồ sơ . Bạn có thể sử dụng chúng để thực sự đo phần nào trong chương trình của bạn mất nhiều thời gian nhất để thực hiện, vì vậy, nơi tập trung nỗ lực điều chỉnh của bạn.

Điều quan trọng không kém là đo lại sau khi thay đổi, để xác minh rằng những thay đổi của bạn có hiệu quả như mong muốn.


5

Nhìn vào số lượng bộ nhớ mà chương trình của bạn sử dụng, không chỉ tốc độ hay thời gian chạy.

Rất nhiều lập trình viên làm việc với các ngôn ngữ được thu gom rác như Java bị ấn tượng nhầm là bộ sưu tập rác ngăn chặn rò rỉ bộ nhớ. Đó không phải là tình huống. Nếu bạn giữ một tham chiếu đến một đối tượng bạn không cần nữa, nó sẽ không được thu thập và vì vậy nó sẽ bị rò rỉ.

Tôi đã thấy các ứng dụng web Java bị rò rỉ đến mức chúng sẽ chạy máy chủ của chúng ra khỏi không gian trao đổi!

Nếu bạn sử dụng cả trình lược tả thời gian chạy và một số cách trình lược tả bộ nhớ, bạn sẽ học cách viết mã nhanh hơn và gọn hơn bằng trực giác. Điều này có tác dụng là mã của bạn có nhiều khả năng chạy nhanh trong lần thử đầu tiên.


1

Biện pháp của tôi là bắt đầu bằng cách nhận được câu trả lời rõ ràng cho hai câu hỏi:

  1. làm thế nào để đo hiệu suất (ví dụ: đo thời gian tải dữ liệu )
  2. giá trị mục tiêu là bao nhiêu (ví dụ: tải dữ liệu trong 3 giây trở xuống với độ tin cậy 95% )

Học được mẹo trên từ những người trong đội hổ đã từng được mời để cứu một bản phát hành bị hỏng của sản phẩm của chúng tôi. Bản phát hành đó đã bị phá vỡ vì lý do hiệu suất, nó có thể khiến công ty mất khách hàng chiến lược, điều đó biện minh cho sự tham gia của những kẻ hổ (khá đắt btw). Tôi được phân công hỗ trợ họ làm rõ chi tiết dự án; cũng sử dụng điều này như một cơ hội để tìm hiểu một hoặc hai về hiệu suất.


1

Những gì tôi đã tìm thấy là thuốc giải độc tốt nhất để tối ưu hóa sớm là phương pháp này .

Khi bạn đã sử dụng nó để tăng tốc một số mã (như trong ví dụ này ), nó sẽ trở thành nghiện của chính nó và bạn hiểu nguyên tắc đầu tiên của việc điều chỉnh hiệu suất không phải là điều chỉnh mã, đó là vấn đề .

Tối ưu hóa thực sự là tối ưu hóa sớm vì săn bắn để nuôi gia đình bạn là bắn lon thiếc. Đó là tất cả về việc tìm kiếm mỏ đá.


1
Và thật không may, bạn chỉ có thể mang 200 bảng về cho gia đình, vì vậy đừng bắn sóc cả ngày.
Jordan

1

Câu hỏi cũ, nhưng tôi sẽ đưa ra câu trả lời này khác với những câu hỏi khác.

Các cơ hội lớn để đạt được hiệu suất đến từ xử lý song song. Cố gắng thiết kế mã của bạn để tận dụng nhiều luồng. (Ngay cả khi, để đơn giản, bạn không làm như vậy trong phiên bản 1). Ít phỏng đoán hoặc trực giác cần thiết.

Bất cứ điều gì khác là tối ưu hóa sớm, và đòi hỏi trực giác của bạn, điều này thường sai.


Điểm thực sự tốt. Trước đây, bạn có thể tin tưởng vào bộ vi xử lý sẽ nhanh hơn sau mỗi vài năm. Bây giờ bạn chỉ nên mong đợi rằng sẽ có nhiều bộ xử lý hơn.
JimmyJames

0

Trực giác của bạn có thể cải thiện theo thời gian. Tôi sẽ ném nó ra, có thể gây tranh cãi một chút, nhưng qua nhiều năm sử dụng VTune và CodeAnalyst và bây giờ là CodeXL, tôi nói rằng tôi chính xác hơn nhiều về trực giác của mình so với trước đây về các điểm nóng, ít nhất là điểm mà tôi không còn mất cảnh giác khi tôi lập hồ sơ một số mã. Điều đó không có nghĩa là tôi cố gắng tối ưu hóa mọi thứ một cách mù quáng.

Hồ sơ đã thực sự làm tăng sự phụ thuộc của tôi vào hồ sơ, không làm giảm nó. Tôi chỉ nói rằng tôi có thể dễ dàng dự đoán kết quả hồ sơ hơn ở mức độ nào và hơn nữa, loại bỏ thành công các điểm nóng và cải thiện thời gian cần thiết để hoàn thành thao tác kết thúc người dùng mà không bị đâm mù trong bóng tối và mất tích (điều gì đó bạn có thể làm ngay cả khi sử dụng một trình lược tả cho đến khi bạn bắt đầu hiểu không chỉ các điểm nóng là gì, mà tại sao chính xác chúng là các điểm nóng liên quan đến, giả sử, bộ nhớ cache bị mất).

Tuy nhiên, phải đến khi tôi bắt đầu sử dụng trình biên dịch, tôi mới bắt đầu cải thiện trực giác đó. Một trong những lý do là bởi vì nếu bạn đã quen thuộc với mã của mình, linh cảm của bạn có thể đúng với các điểm nóng lớn nhất và rõ ràng nhất, nhưng không phải là tất cả sự tinh tế ở giữa. Đương nhiên, nếu bạn có một hoạt động kết thúc người dùng mất một giờ để hoàn thành và có một thuật toán phức tạp bậc hai xử lý một đầu vào trải rộng hàng trăm nghìn phần tử, bạn có thể tiết kiệm được toàn bộ số tiền tiết kiệm cả đời của mình với ý tưởng rằng đó là độ phức tạp bậc hai thuật toán có lỗi ở đây. Nhưng điều đó không cung cấp cho bạn bất kỳ cái nhìn sâu sắc chi tiết nào hoặc, nói, cho bạn biết chính xác những gì không đóng góp cho thời gian.

Có rất nhiều giá trị cần có khi bạn bắt đầu lập hồ sơ và thấy nơi tất cả những điều bạn nghĩ có thể là một đóng góp lớn hơn của thời gian không đóng góp nhiều thời gian; không phải là nguồn gây ra sự thiếu hiệu quả rõ ràng mà là những nguồn bạn nghi ngờ có thể hơi kém hiệu quả, nhưng sau khi định hình, nhận ra rằng họ hầu như không đóng góp bất cứ lúc nào. Và đó có khả năng là nơi bạn có được cái nhìn sâu sắc trực quan nhất là thấy mình bị thể hiện sai trong tất cả những lĩnh vực tinh tế mà không rõ ràng chính xác là đã dành bao nhiêu thời gian.

Trực giác của con người vượt ra ngoài sự phức tạp thuật toán rõ ràng thường sẽ bắt đầu không chính xác bởi vì những gì hiệu quả cho máy móc và những gì hiệu quả cho tâm trí con người là rất khác nhau. Ban đầu, không có gì là trực giác khi nghĩ về hệ thống phân cấp bộ nhớ đi từ các thanh ghi đến bộ đệm CPU đến DRAM vào đĩa. Sẽ không trực giác khi nghĩ rằng số học dư thừa có thể nhanh hơn so với việc truy cập nhiều nhánh hoặc truy cập bộ nhớ của bảng tra cứu để bỏ qua một số công việc xử lý. Chúng ta có xu hướng suy nghĩ về việc có bao nhiêu công việc phải làm trong khi giảm giá những thứ như chi phí đưa ra quyết định và tải bộ nhớ và cửa hàng. Những gì hiệu quả cho phần cứng thường rất phản trực quan theo những cách sẽ phá vỡ mọi giả định của con người bạn bắt đầu,

Nơi cải thiện trực giác đó có thể giúp, thông qua hồ sơ, là thiết kế giao diện . Thiết kế giao diện rất tốn kém để thay đổi trong nhận thức muộn, với chi phí tăng tỷ lệ thuận với số lượng địa điểm tùy thuộc vào giao diện đó. Khi bạn bắt đầu cải thiện trực giác của mình, bạn có thể bắt đầu thiết kế giao diện tốt hơn ngay từ lần đầu tiên theo cách rời khỏi phòng thở để tối ưu hóa trong tương lai mà không phải thay đổi thiết kế tốn kém. Mặc dù vậy, một lần nữa, trực giác đó là thứ bạn thường phát triển và tiếp tục phát triển vô thời hạn, bằng cách luôn có sẵn hồ sơ đó.


0

Profiler giúp sửa chữa trực giác xấu khi nói đến mã. Cho biết bao nhiêu phần cứng dự đoán những ngày này không thực tế để dự đoán hiệu năng của mã của bạn, nhưng điều đó vẫn đúng trong thời gian của Knuth, nhiều thập kỷ trước đã ủng hộ rằng các trình biên dịch nên được đưa vào như một phần của các công cụ tiêu chuẩn để phát triển để khắc phục Bản chất "dại dột" của các nhà phát triển. Nhưng tôi sẽ đi một con đường rất khác với câu trả lời này dựa trên mức độ toàn diện của các câu trả lời và nói rằng sự hiểu biết của người dùng là "cách khắc phục" khác.

Theo kinh nghiệm cá nhân của tôi, tôi đã chứng kiến, một nhà phát triển đặc biệt xuất sắc (nhưng có những điểm mù về cách người dùng thực sự sử dụng phần mềm) tối ưu hóa thuật toán phân chia với trình biên dịch (một công cụ rất tốt và đắt tiền: VTune của Intel với biểu đồ cuộc gọi lấy mẫu trên các trình biên dịch GPU) cho các mắt lưới đạt được kết quả đáng kinh ngạc với hàng tỷ khía cạnh trên GPU khi chia các nguyên thủy đơn giản như hình khối với 6 đa giác lồng / đầu vào. Ngoại trừ anh ta điều chỉnh và điều chỉnh nó với trường hợp thử nghiệm không giống với bất kỳ trường hợp sử dụng nào trong thế giới thực (người dùng không muốn một tỷ mặt cho một khối được chia nhỏ bắt đầu giống như một hình cầu hoàn hảo, các đầu vào phân khu của họ có xu hướng giống như các nhân vật và phương tiện và các đầu vào phức tạp khác).

Thật thú vị, tôi đã tiến xa hơn với một nửa bộ não có chức năng như anh ấy và không có bằng tiến sĩ trong sự nghiệp của tôi vì lý do đơn thuần là tôi hiểu người dùng muốn gì, tiếp thị muốn gì, nhà thiết kế muốn gì. Tôi thực sự không thể nhấn mạnh đủ mức độ hữu ích của việc có thể đặt mình vào suy nghĩ và đôi giày của người dùng và xem phần mềm của bạn và những gì nó cần làm như những người dùng thực tế của bạn trong khi cố gắng tự ly dị với những nỗ lực bạn đặt ra xây dựng những gì bạn xây dựng và nhìn nó với một đôi mắt mới. Tôi thậm chí đã gặp phải từ nhà phát triển ở trên rằng đây là một điều không thể làm được; anh ấy nghĩ rằng tôi có tội khi có một bản ngã tương tự mà tất cả các nhà phát triển am hiểu về kỹ thuật nhưng không biết gì về người dùng, và tôi đã liên tục chứng minh anh ấy sai khi người dùng và nhà thiết kế đổ xô cho tôi nói về chính xác những gì cần làm. Điều đó nghe có vẻ rất tự cao nhưng tôi sẽ cân bằng với từ chối trách nhiệm rằng tôi không phải là một lập trình viên xuất sắc như vậy, nhưng tôi hiểu người dùng và nhà thiết kế muốn gì, và điều đó khiến tôi đặc biệt yêu thích trong lĩnh vực của mình, nơi điều này dường như rất hiếm chất lượng vì một số lý do. Là những lập trình viên, có lẽ chúng ta đã quen với việc kiểm tra hơn là hiểu và giao tiếp với những người bình thường, không có kỹ thuật.

Vì vậy, có hồ sơ và đo lường chính xác nhưng cũng có nhu cầu cơ bản để đảm bảo rằng bạn đang đo một hoạt động với loại đầu vào mà người dùng trong thế giới thực sẽ cung cấp cho ứng dụng. Nếu không, bạn thậm chí có thể có VTune hoặc CodeAnalyst hoặc gprof hoặc bất kỳ trình lược tả nào khác trong tay, trong khi cố gắng tối ưu hóa các điểm nóng chống lại trường hợp thử nghiệm bình thường đối với nhà phát triển nhưng lại gây khó hiểu cho người dùng, kết thúc bi quan về trường hợp sử dụng chung ủng hộ một số trường hợp sử dụng tối nghĩa mà ít người dùng, nếu có, từng cân nhắc áp dụng.

Vào cuối ngày, tất cả những điều không thực tế mà chúng ta có xu hướng mang theo là các nhà phát triển có thể cân bằng với búa sắt khiến người dùng thực sự hạnh phúc mà không cần giải quyết nạn đói thế giới, và nhu cầu thực tế để có tiền để chúng ta có thể trả tiền thuê hoặc mua bia hoặc nhìn vào phụ nữ khỏa thân hoặc bất cứ điều gì bạn muốn / cần làm. Mọi thứ khác đều có khả năng hoạt động chống lại nhu cầu kinh doanh cơ bản đó, và bất kỳ nhà phát triển nào cũng cao quý, anh hùng đến mức quên rằng đây là về việc kiếm tiền và cuối cùng làm hài lòng người dùng để họ trả tiền có thể làm tốt việc đưa mình xuống trái đất và tắt chế độ thần tạo ra thế giới ảo có lợi cho thế giới thực chỉ cần vận chuyển và nhận một số tiền cho thực phẩm. Chúng ta có thể bị lạc trong các số liệu và thực hành phần mềm nhưng về cơ bản là như vậ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.