Trong lĩnh vực công nghệ thông tin, "tối ưu hóa chương trình" không chỉ là một thuật ngữ mà nó còn là một nghệ thuật bao gồm việc tối ưu hóa tất cả các khía cạnh của hệ thống phần mềm để tối đa hóa hiệu quả, mức sử dụng tài nguyên và trạng thái lý tưởng tương đối. Mục đích của việc tối ưu hóa chương trình là làm cho chương trình hoạt động tốt hơn về tốc độ chạy, mức sử dụng bộ nhớ, v.v. và thậm chí đạt được mức tiêu thụ điện năng thấp hơn trong một số trường hợp.
Mặc dù từ "tối ưu hóa" có cùng từ nguyên với "tối ưu hóa", trên thực tế rất hiếm khi thực sự đạt được một hệ thống tối ưu.
Thông thường, một hệ thống được tối ưu hóa sẽ không tối ưu theo nghĩa tuyệt đối mà sẽ được tối ưu hóa dựa trên các thước đo chất lượng cụ thể. Điều này có nghĩa là trong các tình huống ứng dụng khác nhau, các phương pháp tối ưu hóa cần thiết có thể khác nhau. Ví dụ: nếu mức tiêu thụ bộ nhớ tăng lên để tăng tốc độ thực hiện chương trình, điều này có thể không hoàn toàn áp dụng được cho mọi tình huống.
Quá trình tối ưu hóa có thể diễn ra ở nhiều cấp độ, từ cấp độ thiết kế đến các lựa chọn cấu trúc dữ liệu và thuật toán cụ thể hơn và cuối cùng là cấp độ mã nguồn. Các mức độ tối ưu hóa khác nhau có tác động khác nhau đến thành phẩm. Thông thường, mức độ tối ưu hóa càng cao thì hậu quả của những thay đổi sẽ càng lớn và khó điều chỉnh sau này trong dự án.
Hiệu suất là một phần đặc điểm kỹ thuật của chương trình: nếu chương trình chạy chậm thì nó không phù hợp với mục đích.
Tối ưu hóa ở cấp độ thiết kế có thể liên quan đến việc tận dụng tốt nhất các tài nguyên sẵn có nhưng tính hiệu quả cũng rất quan trọng khi chọn thuật toán và cấu trúc dữ liệu. Nếu thiết kế bị giới hạn về độ trễ mạng, bạn có thể chọn giảm yêu cầu dữ liệu và tránh phải thực hiện nhiều chuyến đi khứ hồi.
Việc lựa chọn cấu trúc dữ liệu và thuật toán hiệu quả có thể ảnh hưởng đáng kể đến hiệu quả chung của chương trình. Đặc biệt trong lập trình, cấu trúc dữ liệu thường khó thay đổi hơn các hàm thành viên. Do đó, khi chọn một thuật toán cụ thể, người ta nên tập trung vào việc đảm bảo rằng độ phức tạp về thời gian của nó nằm trong phạm vi hợp lý, chẳng hạn như hằng số O(1) hoặc logarit O(log n). Một thay đổi nhỏ, chẳng hạn như sử dụng kỹ thuật tối ưu hóa "đường dẫn nhanh", thường dẫn đến cải thiện hiệu suất đáng kể.
Ở cấp độ mã nguồn cụ thể, một số lựa chọn nhất định cũng có thể gây ra sự khác biệt đáng kể về hiệu suất. Ví dụ: trong các trình biên dịch C đời đầu, while(1)
hoạt động chậm hơn một chút so với for(;;)
khi thực hiện bước nhảy có điều kiện, vì trình biên dịch trước cần đánh giá điều kiện. Nhưng khả năng tối ưu hóa sự kiện của trình biên dịch ngày nay đã được cải thiện rất nhiều.
Các chương trình được tạo tự động bằng trình biên dịch tối ưu hóa thường có thể đảm bảo mức độ tối ưu hóa nhất định. Các lựa chọn về mức tải trình biên dịch ngày nay cũng có thể mang lại những cải tiến về hiệu suất cho chương trình của bạn. Tuy nhiên, bên cạnh những nỗ lực trên, khi ngưỡng kỹ thuật ngày càng cao hơn, các trình biên dịch hiện đại đã phát triển để có thể xử lý các mã tương đối phức tạp và thực hiện tối ưu hóa.
Trong thời gian chạy, một số trình biên dịch tạo mã máy tùy chỉnh dựa trên dữ liệu hiện tại, điều này thể hiện những ưu điểm của công nghệ biên dịch đúng lúc. Những công nghệ như vậy có thể điều chỉnh dựa trên thông tin đầu vào trong thế giới thực, cho phép kết hợp giữa tính linh hoạt và tối ưu hóa năng động. Kết quả là hiệu suất sẽ được cải thiện tùy thuộc vào môi trường thời gian chạy.
Mặc dù việc tối ưu hóa có thể cải thiện hiệu quả thực thi mã nhưng đôi khi nó cũng làm tăng độ khó của việc bảo trì, do đó việc tối ưu hóa thường được thực hiện vào cuối giai đoạn phát triển. Như Donald Knuth đã nói: "Chúng ta nên quên đi những hiệu quả nhỏ và không nên suy nghĩ quá nhiều trong 97% thời gian; nhưng trong 3% thời gian quan trọng, chúng ta không nên bỏ lỡ cơ hội." quá trình, phải cân bằng cấu trúc và hiệu suất của mã.
"Tối ưu hóa nâng cao là gốc rễ của mọi tội lỗi."
Trong bối cảnh đó, các lập trình viên ngày nay, đứng trước sự cân bằng giữa tiến bộ công nghệ và hiệu quả thực tế, họ nên chọn con đường tốt nhất như thế nào để đạt được trạng thái lý tưởng nhất cho mã chương trình của mình?