Cho Phép Tính Toán Trong Quá Trình Biên Dịch Của Lua
Lua là một ngôn ngữ lập trình có nhiều kỹ thuật tinh vi, khi sử dụng cần cân nhắc kỹ lưỡng. Trong mã nguồn của dự án Kepler, bạn sẽ thấy kỹ thuật biên dịch lặp lại được áp dụng rất sáng tạo, thậm chí có trường hợp biên dịch nhiều lần liên tiếp. Cụ thể, khi tải mã nguồn lần đầu, một đoạn chương trình Lua sẽ được thực thi để tạo ra mã nguồn thực sự cần thiết, sau đó biên dịch đoạn mã này.
Với tốc độ biên dịch cực nhanh của Lua, quá trình biên dịch lặp này chỉ diễn ra duy nhất một lần khi chương trình khởi động, từ đó mang lại hiệu suất cao. Những tham số có thể xác định ngay khi khởi tạo hệ thống (như dữ liệu đọc từ tệp cấu hình) sẽ được biên dịch trực tiếp thành hằng số trong chương trình.
Dưới đây là một đoạn mã nhỏ do chuyên gia Van Phong phát triển nhằm đơn giản hóa quy trình biên dịch lặp này, như một thú vui cuối tuần của ông:
Ví dụ 1: Tạo hằng số từ cấu hình
|
|
Trong ví dụ này, giá trị kết thúc vòng lặp được lấy từ hàm config "max"
. Nếu mỗi lần chạy đều truy vấn cấu hình sẽ gây lãng phí tài nguyên. Với kỹ thuật này, giá trị chỉ cần được lấy duy nhất một lần khi tải chương trình. Ký hiệu | ... |
cho biết đoạn mã bên trong sẽ được thực thi khi tải chương trình, tương tự như kỹ thuật template trong PHP.
Ví dụ 2: Biến template
|
|
Biến ALPHA
được gán giá trị π/4 trong giai đoạn tiền xử lý. Kết quả 0.78539816339745 sẽ được biên dịch trực tiếp vào mã thực thi, trong khi ALPHA
chỉ tồn tại trong quá trình tiền xử lý.
Ví dụ 3: Hàm unpack nâng cao
|
|
Sử dụng hàm này:
|
|
Đoạn mã trên sẽ in ra 1, 2, 3 theo thứ tự quy định trong mảng tham số. Tuy nhiên, nếu gọi hàm như sau:
|
|
Mảng {"one","two","three"}
sẽ được tạo mới mỗi lần gọi hàm, gây lãng phí bộ nhớ. Với kỹ thuật template, ta có thể tối ưu như sau:
|
|
Cơ chế hoạt động của template
- Khi gặp đoạn mã trong
|...|
, hệ thống sẽ thực thi ngay và chèn kết quả vào mã nguồn - Với kiểu dữ liệu đơn giản (nil, boolean, number, string), giá trị sẽ được chèn trực tiếp
- Với kiểu phức tạp, hệ thống tạo biến local để lưu trữ
- Đặc biệt, với cú pháp
|# ... |
, kết quả phải là chuỗi và sẽ được chèn nguyên vẹn vào mã nguồn
Ví dụ 4: Tính năng include
|
|
Sử dụng:
|
|
Tệp local.lua
sẽ được chèn trực tiếp vào mã nguồn như thể bạn viết thủ công tại vị trí đó.
Kỹ thuật này đặc biệt hữu ích để tối ưu hiệu suất bằng cách:
- Biến các giá trị cấu hình thành hằng số
- Tránh tạo đối tượng lặp đi lặp lại
- Tự động chèn mã tiền xử lý
Toàn bộ cơ chế có thể được triển khai dễ dàng bằng chính Lua. Bạn có thể tham khảo mã nguồn đầy đủ tại đây (liên kết giả định).