Tại Sao Phiên Bản Mới Của Lua Lại Ngày Càng Chậm? - nói dối e blog

Tại Sao Phiên Bản Mới Của Lua Lại Ngày Càng Chậm?

Tại sao phiên bản mới của Lua lại ngày càng chậm hơn?

Tại sao các phiên bản Lua mới ngày càng chậm hơn?

Có người vừa gửi cho tôi một bài viết trên Zhihu với tiêu đề: “Tại sao Lua 5.3 lại chậm? Có nên nâng cấp không?”. Qua quá trình nghiên cứu kỹ lưỡng và hàng loạt thí nghiệm thực tế, tôi xin chia sẻ góc nhìn chuyên sâu về vấn đề này.

Trước hết, sự chênh lệch 10% về hiệu năng không phải là con số quá lớn. So với việc đánh đổi 10% hiệu năng để có được mã nguồn rõ ràng hơn, hệ thống ổn định hơn và khả năng xử lý các tình huống biên tốt hơn (ý nhấn mạnh vào tính toàn diện của mã nguồn chứ không đơn thuần là tăng thêm chức năng), thì sự hy sinh này hoàn toàn hợp lý. Đặc biệt trong thời đại phần cứng phát triển như vũ bão hiện nay, việc tăng cường 10% hiệu năng CPU là điều dễ dàng thực hiện.

Thực tế trong các dự án thực tế, khác với các script kiểm tra đơn giản, sự khác biệt 10% này gần như không thể nhận thấy. Bằng chứng là chúng tôi đã triển khai cả Lua 5.2 và 5.3 trên hệ thống server nhưng không ghi nhận sự khác biệt rõ rệt nào về hiệu năng vận hành.

Xét về mặt lịch sử, nếu so sánh bằng các script đơn giản, phiên bản Lua 5.1 còn chậm hơn đáng kể so với phiên bản tiền nhiệm 5.0 của chính nó. Khoảng cách này thậm chí còn lớn hơn sự chênh lệch giữa 5.1 và 5.3. Tuy nhiên vì sao không nhiều người quay lại dùng phiên bản 5.0? Câu trả lời nằm ở sự phân mảnh cộng đồng Lua do sự ra đời của Luajit - khiến phiên bản trung gian 5.1 dường như trở thành một ngôn ngữ Lua độc lập.

Tôi vẫn giữ lại các bản source code từ phiên bản 4.0 đến nay, đồng thời theo dõi sát sao các thay đổi qua từng phiên bản trong suốt 10 năm qua. Từ kinh nghiệm nghiên cứu chuyên sâu, tôi xin phân tích các nguyên nhân chính gây ra hiện tượng chậm dần này.

Qua 1 ngày thực nghiệm đầy đủ từ profiling, phân tích mã hợp ngữ đến so sánh diff giữa các phiên bản, tôi nhận thấy sự sụt giảm hiệu năng 5-10% trong các benchmark đơn giản chủ yếu đến từ:

  1. Tăng cường tính ổn định: Các phiên bản mới bổ sung nhiều cơ chế kiểm tra xử lý tình huống biên, hoàn thiện các chức năng chưa trọn vẹn. Ví dụ rõ ràng là ở phiên bản 5.1 không cho phép yield trong pcall hay hook, nhưng các phiên bản sau đã loại bỏ giới hạn này thông qua thiết kế lại toàn diện.

  2. Cải tiến hệ thống GC: Quá trình phát triển không ngừng của module garbage collection đòi hỏi những thay đổi tất yếu nhưng ảnh hưởng đến hiệu năng.

  3. Phân loại kiểu dữ liệu nội bộ: Việc chia number thành integer và float từ phiên bản 5.3 thường bị cho là gây ra các rẽ nhánh thừa. Thực tế phân tích cho thấy chi phí bổ sung này cực kỳ nhỏ, đặc biệt với các thao tác index bảng thông thường.

Một ví dụ thú vị là sự thay đổi từ Lua 5.2.0 sang 5.2.1, khi hệ thống bắt đầu dùng bit cao của type field để phân biệt sub-type. Việc phân loại string thành ngắn/dài khiến nhiều người lo ngại hiệu năng, nhưng qua kiểm tra kỹ lưỡng, sự khác biệt chỉ dao động 1% và phụ thuộc vào cách viết script cụ thể.

Vấn đề thực sự xuất phát từ đâu? Đáng ngạc nhiên, phần lớn sự chậm lại đến từ:

  • Vòng lặp for số học: Lua 5.3 thêm bước kiểm tra sub-type cho biến lặp, gây ảnh hưởng rõ rệt trong các benchmark tập trung vào vòng lặp đơn giản. Tuy nhiên trong thực tế, thời gian chiếm dụng CPU của vòng lặp thuần hiếm khi đạt mức đáng lo ngại.

  • Truy cập biến toàn cục: Việc loại bỏ khái niệm môi trường cấp C từ 5.2 khiến thao tác truy cập _ENV (thay thế cho biến toàn cục) chậm hơn chút ít. Một mẹo tối ưu đơn giản là dùng biến local thay thế: thêm dòng ’local math = math’ sẽ xóa bỏ khác biệt hiệu năng giữa các phiên bản.

Thú vị hơn, nếu không trộn lẫn integer và float, Lua 5.3 có thể chạy nhanh hơn nhờ hỗ trợ nguyên thủy 64-bit và các phép toán bitwise cấp ngôn ngữ - mang lại lợi thế rõ rệt cho các lĩnh vực xử lý số học phức tạp.

Cần lưu ý rằng sự đánh đổi này là tất yếu trong quá trình phát triển. Phiên bản 5.0 được viết lại hoàn toàn từ 4.0 đã mang đến bước đột phá về hiệu năng. Có lẽ chúng ta nên kỳ vọng vào một Luajit 2.0 hay thậm chí là Lua 6 với thiết kế cách mạng mới.

Các bạn có thể tải toàn bộ source code các phiên bản Lua tại đây để tự nghiệm chứng. Mỗi sự nghi ngờ đều cần được xác minh thông qua thực tiễn - đó chính là tinh thần của developer chuyên nghiệp.

0%