2009-03-31 31 views
10

Một trong những câu thần chú phổ biến nhất trong khoa học máy tính và lập trình là không bao giờ tối ưu hóa sớm, có nghĩa là bạn không nên tối ưu hóa bất cứ điều gì cho đến khi một vấn đề được xác định, vì khả năng đọc/bảo trì mã có thể bị ảnh hưởng.Tối ưu hóa nào là OK để thực hiện ngay?

Tuy nhiên, đôi khi bạn có thể biết rằng một cách làm việc cụ thể sẽ hoạt động kém. Khi nào thì OK để tối ưu hóa trước khi xác định sự cố? Những loại tối ưu hóa nào được cho phép ngay từ đầu?

Ví dụ, sử dụng càng ít kết nối DB càng tốt, và chú ý tới rằng trong khi đang phát triển, thay vì sử dụng một kết nối mới khi cần thiết và lo lắng về chi phí hoạt động sau

+0

Wiki cộng đồng ?? –

+0

Trong ví dụ của bạn, có bất biến vòng lặp bên trong vòng lặp là thực hành lập trình kém và cần được ghi lại lý do tại sao nó nằm trong vòng lặp cho một vài trường hợp ngoại lệ, nơi nó có thể cần thiết. – Elie

Trả lời

26

Tôi nghĩ rằng bạn đang thiếu điểm của nguyên tắc đó. Không có gì sai khi thực hiện điều gì đó hiệu quả nhất có thể ngay từ đầu, được cung cấp cũng rõ ràng, thẳng về phía trước, v.v.

Vấn đề là bạn không nên tự buộc mình (và tệ hơn, mã của bạn) theo nút cố gắng giải quyết các vấn đề có thể không tồn tại. Tiết kiệm mức độ tối ưu hóa cực kỳ đó, thường tốn kém về mặt phát triển, bảo trì, nợ kỹ thuật, cơ sở sinh sản lỗi, tính di động, v.v. trong trường hợp bạn thực sự cần.

3

Nếu bạn không có một vấn đề hiệu suất, sau đó bạn không nên hy sinh khả năng đọc cho hiệu suất. Tuy nhiên, khi chọn một cách để thực hiện một số chức năng, bạn nên tránh sử dụng mã mà bạn biết là có vấn đề từ quan điểm hiệu năng. Vì vậy, nếu có 2 cách để thực hiện một chức năng, hãy chọn một cách để thực hiện tốt hơn, nhưng nếu đó không phải là giải pháp trực quan nhất, hãy đảm bảo bạn đưa vào một số nhận xét về lý do tại sao bạn mã hóa theo cách đó.

14

Tôi nghĩ rằng bạn đang xem xét điều này một cách sai lầm. Điểm tránh tối ưu hóa sớm không phải là để tránh tối ưu hóa, nó là để tránh những suy nghĩ bạn có thể rơi vào.

Viết thuật toán của bạn theo cách rõ ràng nhất mà bạn có thể đầu tiên. Sau đó, hãy chắc chắn nó là chính xác. Sau đó (và chỉ sau đó) lo lắng về hiệu suất. Nhưng cũng nghĩ về bảo trì, v.v.

Nếu bạn làm theo cách tiếp cận này, thì câu hỏi của bạn sẽ tự trả lời. Chỉ "tối ưu hóa" được cho phép ngay từ đầu là những tối thiểu rõ ràng là cách tiếp cận đơn giản.

+0

Tôi thứ hai là .. Nếu tôi có thể cung cấp cho bạn 10 phiếu bầu, tôi sẽ ... –

4

IMHO, không có. Viết mã của bạn mà không bao giờ nghĩ đến "tối ưu hóa". Thay vào đó, hãy suy nghĩ "rõ ràng", "đúng đắn", "khả năng bảo trì" và "khả năng thử nghiệm".

+0

Tất nhiên ... Tôi xem xét từng tối ưu hóa đó. :) – Randolpho

+0

Vâng, đó là tốt nếu bạn đang phát triển một trang web hoặc GUI, nhưng tôi sẽ đặt cược rằng các lập trình viên hệ thống nhúng sẽ không đồng ý với bạn. –

+0

@ed - khả năng tâm linh của bạn đã làm hỏng bạn - Tôi không làm các trang web hoặc GUI. –

-2

Không gọi Collection.ElementCount trực tiếp trong biểu thức kiểm tra vòng lặp nếu bạn biết chắc chắn giá trị này sẽ được tính trên mỗi thẻ.

Thay vì:

for (int i = 0; i < myArray.Count; ++i) 
{ 
    // Do something 
} 

Đỗ:

int elementCount = myArray.Count; 
for (int i = 0; i < elementCount ; ++i) 
{ 
    // Do something 
} 

Một trường hợp cổ điển.

Tất nhiên, bạn phải biết loại bộ sưu tập đó là gì (thực sự, cách tính/phương thức Count được triển khai). Có thể không nhất thiết phải tốn kém.

+0

Hmm. Không phải là tối ưu hóa thực sự không đặt những thứ được tính trên mỗi pass trong một tài sản? Làm cho nó một chức năng và nó sẽ được rõ ràng. – Jerph

+0

Không bao giờ nghe nói về cách tiếp cận đó thực sự ... Tuy nhiên, điều mà một số người sẽ không nghĩ ra rằng thậm chí gọi một phương pháp trong một vòng lặp có thể là xấu. – User

+0

Tôi sẵn sàng đặt cược, hầu hết thời gian/số đếm của mảng/bộ sưu tập là hoạt động O (1). Vì vậy, tôi sẽ phải không đồng ý. –

6

Tối ưu hóa tốt nhất bạn có thể thực hiện tại mọi thời gian là chọn thuật toán chính xác cho sự cố. Thật ngạc nhiên khi một suy nghĩ nhỏ tạo ra một cách tiếp cận tốt hơn sẽ tiết kiệm được nhiều đơn đặt hàng, thay vì một vài phần trăm. Đó là một chiến thắng hoàn toàn.

Những điều cần tìm kiếm:

  • công thức toán học chứ không phải lặp đi lặp lại.
  • Các mẫu nổi tiếng và được ghi lại.
  • hiện mã/linh kiện
2

Khi bạn phát triển trong sự nghiệp của bạn như là một nhà phát triển, bạn sẽ chỉ đơn giản là phát triển trong nhận thức về tốt hơn, cách tiếp cận hợp lý hơn cho những vấn đề khác nhau. Trong hầu hết các trường hợp, tôi có thể nghĩ đến, công việc nâng cao hiệu suất dẫn đến mã thực sự nhỏ hơn và đơn giản hơn một số mớ phức tạp phát triển do làm việc thông qua một vấn đề. Khi bạn trở nên tốt hơn, các giải pháp đơn giản hơn, nhanh hơn trở nên dễ dàng hơn và tự nhiên hơn để tạo ra.

Cập nhật: Tôi đang bỏ phiếu +1 cho tất cả mọi người trong chuỗi cho đến nay vì câu trả lời rất tốt. Đặc biệt, DWC đã nắm bắt được bản chất của vị trí của tôi với một số ví dụ tuyệt vời.

2

Documentation

Lập tài liệu mã của bạn là # 1 tối ưu hóa (quá trình phát triển) mà bạn có thể làm ngay từ nhận đi. Như các dự án phát triển, càng có nhiều người bạn tương tác với và càng có nhiều người cần phải hiểu những gì bạn đã viết, thời gian hơn bạn sẽ dành

Toolkits

Hãy chắc chắn rằng bộ công cụ của bạn có phù hợp với các ứng dụng mà bạn đang đang phát triển. Nếu bạn đang tạo một ứng dụng nhỏ, không có lý do gì để gọi sức mạnh hùng mạnh của một hệ thống GUI dựa trên Eclipse.

Complilers

Hãy trình biên dịch làm công việc khó khăn. Hầu hết thời gian, tối ưu hóa chuyển mạch trên một trình biên dịch sẽ làm hầu hết những điều quan trọng bạn cần.

Hệ thống tối ưu hóa cụ thể

Đặc biệt trong thế giới nhúng, đạt được một sự hiểu biết về kiến ​​trúc cơ bản của CPU và hệ thống bạn đang tương tác với. Ví dụ, trên một CPU Coldfire, bạn có thể đạt được những cải tiến hiệu suất lớn bằng cách đảm bảo rằng dữ liệu của bạn nằm trên ranh giới byte thích hợp.

Algorithms

Phấn đấu thực hiện các thuật toán truy cập O (1) hoặc O (log n). Phấn đấu để thực hiện lặp qua danh sách không quá O (N). Nếu bạn đang đối phó với một lượng lớn dữ liệu, tránh bất cứ điều gì nhiều hơn O (N^2) nếu nó ở tất cả có thể.

Mã Tricks

Tránh, nếu có thể.Đây là một sự tối ưu hóa trong chính nó - một tối ưu hóa để làm cho ứng dụng của bạn dễ bảo trì hơn trong thời gian dài.

0

Đồng ý với Neil's opinion ở đây, việc tối ưu hóa hiệu suất trong mã ngay lập tức là một thực tiễn phát triển kém.

IMHO, tối ưu hóa hiệu suất phụ thuộc vào thiết kế hệ thống của bạn. Nếu hệ thống của bạn đã được thiết kế kém, từ góc độ hiệu suất, không có tối ưu hóa mã nào sẽ giúp bạn đạt được hiệu suất 'tốt' - bạn có thể có hiệu suất tương đối tốt hơn nhưng hiệu suất không tốt. Ví dụ, nếu có ý định xây dựng một ứng dụng truy cập cơ sở dữ liệu, một mô hình dữ liệu được thiết kế tốt, đã bị khử chuẩn chỉ đủ, nếu có khả năng mang lại các đặc tính hiệu năng tốt hơn so với mô hình dữ liệu được thiết kế kém đã được tối ưu hóa/điều chỉnh để có được hiệu suất tương đối tốt hơn.

Tất nhiên, người ta không được quên các yêu cầu trong hỗn hợp này. Có những yêu cầu hiệu suất tiềm ẩn mà người ta phải cân nhắc trong quá trình thiết kế - thiết kế trang web công khai thường yêu cầu bạn giảm các chuyến đi phía máy chủ để đảm bảo cảm giác 'hiệu suất cao' cho người dùng cuối. Điều đó không có nghĩa là bạn xây dựng lại DOM trên trình duyệt trên mọi hành động và vẽ lại giống nhau (tôi đã thấy điều này trong thực tế), nhưng bạn xây dựng lại một phần của DOM và để trình duyệt thực hiện phần còn lại (được xử lý bởi một nhà thiết kế hợp lý, người hiểu được các yêu cầu tiềm ẩn).

4

Từ wikipedia:

Chúng ta nên quên đi nhỏ hiệu quả, nói rằng khoảng 97% thời gian : tối ưu hóa sớm là gốc của mọi tội lỗi. Tuy nhiên, chúng tôi không nên bỏ qua các cơ hội của chúng tôi trong đó quan trọng 3%. - Donald Knuth

Tôi nghĩ rằng tổng hợp nó lên. Câu hỏi là biết nếu bạn đang ở trong 3% và những gì con đường để có. Cá nhân tôi bỏ qua hầu hết các tối ưu hóa cho đến khi tôi ít nhất có được mã của tôi làm việc. Thông thường như một đường chuyền riêng biệt với một trình hồ sơ để tôi có thể chắc chắn rằng tôi đang tối ưu hóa những thứ thực sự quan trọng. Thông thường, mã lệnh chỉ chạy nhanh đủ để mọi thứ bạn làm sẽ có ít hoặc không có hiệu lực.

0

Chọn cấu trúc dữ liệu thích hợp. Tôi thậm chí không chắc nó được tính là tối ưu hóa nhưng nó có thể ảnh hưởng đến cấu trúc của ứng dụng của bạn (do đó tốt để làm sớm) và tăng hiệu suất rất nhiều.

1

Bạn nên tránh tất cả các tối ưu hóa nếu niềm tin duy nhất mã bạn đang tối ưu hóa sẽ chậm. Mã duy nhất bạn nên tối ưu hóa là khi bạn biết nó là chậm (tốt hơn thông qua một hồ sơ).

Nếu bạn viết mã rõ ràng, dễ hiểu thì tỷ lệ cược sẽ đủ nhanh, và nếu không thì khi bạn tăng tốc nó sẽ dễ làm hơn.

Điều đó đang được nói, thông thường nên áp dụng (!). Bạn có nên đọc lại một lần nữa hay bạn nên lưu lại kết quả? Có lẽ là bộ nhớ cache kết quả. Vì vậy, từ quan điểm kiến ​​trúc mức cao, bạn nên suy nghĩ về tối ưu hóa.

Phần "tà ác" của tối ưu hóa là "tội lỗi" được cam kết trong tên làm một cái gì đó nhanh hơn - những tội lỗi này thường dẫn đến mã rất khó hiểu. Tôi không chắc chắn 100% đây là một trong số họ ..nhưng nhìn vào this question here, điều này có thể hoặc không thể là một ví dụ về tối ưu hóa (có thể là cách mà người đó nghĩ đến), nhưng có nhiều cách rõ ràng hơn để giải quyết vấn đề hơn những gì đã được chọn.

Một điều bạn có thể làm, mà gần đây tôi đã làm, là khi bạn đang viết mã và bạn cần quyết định cách làm một cái gì đó ghi cả hai cách và chạy nó thông qua một hồ sơ. Sau đó chọn cách rõ ràng nhất để mã hóa nó trừ khi có sự khác biệt lớn về tốc độ/bộ nhớ (tùy thuộc vào bạn đang làm gì). Bằng cách đó bạn không đoán được những gì "tốt hơn" và bạn có thể ghi lại lý do tại sao bạn đã làm theo cách đó để một người nào đó không thay đổi nó sau này.

Trường hợp mà tôi đang làm đang sử dụng các tệp ánh xạ bộ nhớ -v-stream I/O ... tệp ánh xạ bộ nhớ nhanh hơn đáng kể so với cách khác, vì vậy tôi không quan tâm liệu mã có khó theo dõi hay không (không phải) vì tốc độ tăng lên đáng kể.

Một trường hợp khác mà tôi đã quyết định là chuỗi "thực tập" trong Java hay không. Làm như vậy sẽ tiết kiệm không gian, nhưng với chi phí thời gian. Trong trường hợp của tôi tiết kiệm không gian không lớn, và thời gian đã tăng gấp đôi, vì vậy tôi đã không thực tập. Tài liệu cho phép người khác biết không làm phiền việc thực tập nó (hoặc nếu họ muốn xem phiên bản Java mới hơn có làm cho nó nhanh hơn thì họ có thể thử).

1

Ngoài việc rõ ràng và đơn giản, bạn cũng phải mất một khoảng thời gian hợp lý để triển khai mã chính xác. Nếu bạn mất một ngày để có được mã hoạt động đúng, thay vì hai giờ nó sẽ thực hiện nếu bạn chỉ viết nó, thì bạn có thể lãng phí thời gian bạn có thể dành cho việc sửa chữa hiệu suất thực thực vấn đề (Knuth 3%).

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