NhaLapTrinh.comNhà Lập Trình
Viết mã dễ đọc

Khi nào mới nên lo tối ưu tốc độ mã?

Nên lo tối ưu tốc độ khi đã có mã chạy đúng, đã đo được chỗ chậm thật, và tốc độ đó thật sự ảnh hưởng tới người dùng hay chi phí. Tối ưu theo cảm tính thường tốn công vào chỗ không quan trọng mà làm mã khó đọc hơn. Ngoại lệ là những lựa chọn lớn như cấu trúc dữ liệu, nên nghĩ từ đầu.

🎙️
📑 Nội dung theo chương
  1. 0:37 Đúng trước, dễ đọc sau, nhanh sau cùng
  2. 1:22 Đo trước khi sửa
  3. 2:10 Điểm nghẽn thường nằm ở đâu?
  4. 2:58 Những lựa chọn nên nghĩ từ đầu
  5. 3:44 Nhanh đến mức nào là đủ?
  6. 4:32 Câu hỏi thường gặp
🔊 Bản audio (lồng nhạc nền)

Nên lo tối ưu tốc độ khi đã có mã chạy đúng, đã đo được chỗ chậm thật sự, và cái chậm đó thật sự ảnh hưởng tới người dùng hoặc tới chi phí. Tối ưu theo cảm tính thường tốn công vào chỗ không quan trọng mà lại làm mã khó đọc hơn. Ngoại lệ là vài lựa chọn lớn như cách tổ chức dữ liệu, những thứ nên nghĩ kỹ ngay từ đầu.

Chào bạn, đây là Nhà Lập Trình. Người mới học lập trình thường mê tốc độ. Họ đọc được rằng cách viết này nhanh hơn cách kia một chút, và dùng nó khắp nơi. Trong nghề có một câu nói nổi tiếng rằng tối ưu quá sớm là gốc rễ của nhiều điều tệ hại. Tập này kể vì sao, và cũng kể khi nào câu đó không đúng.

Đúng trước, dễ đọc sau, nhanh sau cùng

Có một thứ tự ưu tiên mà nhiều người làm nghề lâu đồng ý: làm cho đúng, làm cho rõ, rồi mới làm cho nhanh. Một chương trình nhanh mà sai thì vô dụng. Một chương trình đúng mà hơi chậm thì vẫn dùng được, và có thể làm nhanh hơn sau.

Khi bạn tối ưu trước khi chương trình chạy đúng, bạn tối ưu một thứ còn đang thay đổi. Hôm sau yêu cầu đổi, đoạn mã được tối ưu kỹ bị vứt đi. Công sức đổ sông đổ biển.

Mã được tối ưu thường khó đọc hơn. Nó dùng những thủ thuật, những lối tắt, những cách tổ chức không tự nhiên để đổi lấy tốc độ. Người đọc sau phải hiểu cả logic nghiệp vụ lẫn thủ thuật tối ưu. Nếu tốc độ đó không cần, bạn đã trả giá dễ đọc mà không nhận lại gì.

Nên viết mã rõ ràng trước. Mã rõ ràng cũng dễ tối ưu hơn khi cần, vì bạn thấy rõ nó đang làm gì.

Đo trước khi sửa

Nguyên tắc quan trọng nhất của tối ưu là đo. Trực giác của con người về chỗ chậm trong chương trình sai nhiều đến bất ngờ. Bạn nghĩ vòng lặp này chậm, đo thì thấy nó chỉ chiếm một phần trăm thời gian. Chín mươi phần trăm nằm ở một câu truy vấn cơ sở dữ liệu bạn không ngờ tới.

Có công cụ đo cho phép bạn thấy chương trình dành thời gian ở đâu, hàm nào được gọi bao nhiêu lần, mỗi lần mất bao lâu. Học dùng một công cụ như vậy cho ngôn ngữ của bạn là khoản đầu tư rất đáng.

Khi đo, hãy đo trong điều kiện gần thật: dữ liệu cỡ thật, tải gần thật. Chương trình chạy nhanh với mười dòng dữ liệu thử có thể chậm hoàn toàn khác với một triệu dòng dữ liệu thật.

Đo cả trước và sau khi sửa. Rất nhiều lần, một thay đổi được cho là tối ưu lại không nhanh hơn chút nào, thậm chí chậm hơn. Không đo thì bạn không bao giờ biết.

Điểm nghẽn thường nằm ở đâu?

Trong phần lớn ứng dụng thông thường như trang web, phần mềm quản lý, ứng dụng điện thoại, điểm nghẽn hiếm khi nằm ở việc tính toán trong bộ xử lý. Nó thường nằm ở những chỗ phải chờ: chờ cơ sở dữ liệu, chờ mạng, chờ đọc ghi tệp.

Một lỗi rất hay gặp là hỏi cơ sở dữ liệu trong vòng lặp. Lấy danh sách một trăm đơn hàng, rồi với mỗi đơn lại hỏi riêng thông tin khách hàng. Một trăm lẻ một lần hỏi thay vì hai lần. Mỗi lần chỉ mất một chút, nhưng cộng lại thành cả giây.

Lỗi khác là thiếu chỉ mục trong cơ sở dữ liệu, khiến mỗi lần tìm kiếm phải lật hết cả bảng. Hoặc tải những thứ không cần: lấy toàn bộ cột khi chỉ cần hai cột, tải ảnh gốc năm mươi lần to hơn chỗ hiển thị.

Sửa những điểm nghẽn này thường không làm mã khó đọc hơn, và hiệu quả gấp nhiều lần so với việc đổi vòng lặp này sang vòng lặp kia cho nhanh hơn chút xíu.

Những lựa chọn nên nghĩ từ đầu

Nói vậy không có nghĩa là đừng bao giờ nghĩ về tốc độ lúc đầu. Có những lựa chọn rất khó đổi sau này, và chúng quyết định tốc độ nhiều hơn mọi thủ thuật nhỏ.

Cách tổ chức dữ liệu là lựa chọn lớn nhất. Dùng danh sách hay bảng tra cứu cho một việc cần tìm kiếm liên tục có thể tạo ra khác biệt hàng nghìn lần khi dữ liệu lớn. Thiết kế bảng cơ sở dữ liệu thế nào quyết định truy vấn nhanh hay chậm trong nhiều năm.

Cách các thành phần nói chuyện với nhau cũng vậy. Một hệ thống mà mỗi thao tác của người dùng phải gọi qua lại mười dịch vụ sẽ chậm dù mỗi dịch vụ có nhanh đến đâu.

Nên phân biệt: nghĩ kỹ về những lựa chọn lớn, khó đổi ngay từ đầu, nhưng đừng bận tâm tới những tối ưu nhỏ, dễ đổi cho tới khi đo thấy cần. Đó là cách hiểu đúng câu nói về tối ưu quá sớm.

Nhanh đến mức nào là đủ?

Tối ưu không có điểm dừng tự nhiên, luôn có thể nhanh hơn. Nên cần một mục tiêu: nhanh đến mức nào là đủ. Mục tiêu đó đến từ người dùng và từ chi phí, không phải từ lòng tự hào của lập trình viên.

Với người dùng, có những ngưỡng cảm nhận khá quen thuộc: phản hồi gần như tức thì thì người dùng thấy mượt, chờ một chút thì vẫn chấp nhận, chờ lâu mà không có dấu hiệu gì thì họ nghĩ hỏng và bấm lại. Một báo cáo chạy ban đêm thì mất vài phút cũng không ai phàn nàn.

Với chi phí, một đoạn mã chạy trên hàng trăm máy chủ mỗi ngày thì tối ưu nó tiết kiệm được tiền thật. Một công cụ nội bộ ba người dùng thì tối ưu không đáng công.

Khi đã đạt mục tiêu, hãy dừng lại. Thời gian còn lại dành cho tính năng mới, cho sửa lỗi, cho làm mã dễ đọc hơn. Tốc độ chỉ là một trong nhiều thứ người dùng cần, và thường không phải thứ quan trọng nhất.

Câu hỏi thường gặp

Tối ưu quá sớm là gì?

Là dành công sức làm mã chạy nhanh hơn khi chưa biết chỗ đó có thật sự chậm hay có ảnh hưởng tới người dùng không. Nó thường làm mã khó đọc hơn mà không đổi lại lợi ích đáng kể.

Làm sao biết chỗ nào trong chương trình chạy chậm?

Dùng công cụ đo hiệu năng để xem chương trình dành thời gian ở đâu, trong điều kiện dữ liệu và tải gần với thực tế. Đừng dựa vào trực giác vì trực giác thường sai.

Vì sao trang web chậm dù máy chủ mạnh?

Thường do chờ cơ sở dữ liệu với nhiều truy vấn trong vòng lặp hoặc thiếu chỉ mục, do tải ảnh và tệp quá nặng, hoặc do gọi qua lại nhiều dịch vụ. Sức mạnh máy chủ không bù được những vấn đề này.

Có nên chọn ngôn ngữ lập trình nhanh nhất cho mọi dự án?

Không nhất thiết. Với phần lớn ứng dụng, điểm nghẽn nằm ở cơ sở dữ liệu và mạng hơn là tốc độ ngôn ngữ. Tốc độ phát triển và khả năng bảo trì thường quan trọng hơn.

Tối ưu mã có làm mã khó đọc hơn không?

Thường có, vì tối ưu hay dùng thủ thuật và cách tổ chức không tự nhiên. Nên chỉ tối ưu những chỗ đo thấy thật sự cần, và ghi chú thích giải thích vì sao viết như vậy.

Cần tư vấn cụ thể cho trường hợp của bạn?

Chúng tôi sẽ liên hệ trong vòng 24 giờ.

Đăng ký tư vấn ngay

Bài viết liên quan

Bạn cần hỗ trợ thêm?

Để lại thông tin, chúng tôi sẽ liên hệ trong 24 giờ.