Mở Rộng Kiểu Hằng Số Trong Lua
Gần đây mình có một vài ý tưởng còn khá non nớt liên quan đến Lua.
Hiện tại bảng hằng số trong nguyên mẫu hàm của Lua chỉ hỗ trợ ba kiểu dữ liệu cơ bản là boolean, số học và chuỗi ký tự. Các kiểu phức tạp như hàm hoặc bảng hoàn toàn không thể xuất hiện trong vùng lưu trữ hằng số này.
Mình nghĩ nếu chúng ta có thể vượt qua giới hạn này, cho phép nhiều kiểu giá trị hơn trở thành hằng số, thì sẽ rất hữu ích. Chẳng hạn, một kỹ thuật lập trình thường thấy là viết dòng lệnh:
|
|
Đoạn mã này xuất phát từ nguyên tắc biến cục bộ truy cập nhanh hơn biến toàn cục nhờ bỏ qua bước tra cứu bảng băm. Tuy nhiên trong thực tế, sự chênh lệch hiệu suất thường không đáng kể. Mặt khác, cách làm này lại vô tình tạo thêm các upvalue không cần thiết cho những hàm khác sử dụng pairs
, dẫn đến hiệu quả tổng thể có thể còn kém hơn.
Điều chúng ta thực sự cần là biến pairs
- một hàm C light (light C function) - có thể được xử lý như một hằng số nguyên thủy giống kiểu số 1, 2, 3. Như vậy sẽ tránh tạo ra overhead từ upvalue.
Từ phiên bản Lua 5.4, ngôn ngữ đã hỗ trợ từ khóa const
cho biến cục bộ:
|
|
Tuy nhiên thực tế pairs
ở đây vẫn chưa phải là một hằng số thực thụ. Mình đề xuất sửa đổi ngữ nghĩa của dòng mã này: Khi gán một biến toàn cục cho biến cục bộ có đánh dấu <const>
, Lua nên tiến hành đánh giá giá trị biến toàn cục ngay giai đoạn load
thay vì runtime. Điều này sẽ cho phép đưa pairs
vào bảng hằng số.
Về mặt kỹ thuật, chúng ta hoàn toàn có thể thực hiện điều này bằng cách ghi nhận tên biến toàn cục trong bảng hằng số, và trì hoãn việc giải quyết địa chỉ cụ thể cho đến khi nạp bytecode. Cách tiếp cận này tương tự như việc mỗi chunk Lua đều sở hữu một bảng liên kết các ký hiệu bên ngoài (external symbol table), giúp quá trình load
tiến gần hơn đến cơ chế liên kết (link) của ngôn ngữ tĩnh.
Giải pháp này không chỉ tối ưu hóa hiệu năng mà còn mở đường cho việc tích hợp các trình biên dịch JIT hoặc AOT trong tương lai, giúp chúng hoạt động hiệu quả hơn nhờ vào tính chất định trước của các hằng số.