25.4 Lua Script Performance
There are many ways to measure and improve the performance of a Lua Script running on a T-Series device. A set of benchmarking example scripts are available in the Lua Script Examples and in Kipling.
The analog input benchmark script runs at approximately 12500 loop iterations per second.
The DIO benchmark script runs at approximately 16000 loop iterations per second.
Test Methodology
The performance tests on this page were obtained by measuring the total time it took to run 100000 iterations of a given chunk of Lua code and then dividing that total time by 100,000 to convert to microseconds (μs per iteration). Test results were obtained using a T4 running firmware version 1.0023, default Lua throttling settings, and default processor speed. A T7-Pro running firmware version 1.0282 produced similar results. Execution times can vary by up to 10% with different firmware versions and device types.
Using local
to Improve Lookup Time
Define Variables as local
When performing operations in a scripted language like Lua, it takes time to look up variables depending on their scope. To speed up a script, define variables as local
. For example, the average iteration time for the following script was 17.2 µs:
x = 0
for i = 1, 100000 do
x = x + 1
end
The same script with variable x
defined as a local variable took approximately 8.5 µs per iteration:
local x = 0
for i = 1, 100000 do
x = x + 1
end
Create local
References to Functions
It is also faster to use local
references to functions. The benchmarking example scripts all define local
references to the functions from the Lua LabJack Library, which provides the global MB
and LJ
objects. For example, the average iteration time for the following script was 23.7 µs:
for i = 1, 100000 do
LJ.DIO_S_W(5,1)
end
The same script with a local
reference to LJ.DIO_S_W
as dioStateWrite
took approximately 18.1 µs per iteration.
local dioStateWrite = LJ.DIO_S_W
for i = 1, 100000 do
dioStateWrite(5,1)
end
Adjusting LJ.setLuaThrottle
After a script is successfully downloaded to a device and no RAM errors are encountered, the T-Series device uses its internal Lua compiler to translate (precompile) the source code into a set of instructions similar to machine code but intended for the Lua interpreter. When it is time for the code to be executed, the T-Series device steps through one or more instructions at a time as defined by the LJ.setLuaThrottle function. In practical terms, this setting adjusts the number of Lua machine instruction codes that are executed per service interval. This number can be increased at the expense of potentially preventing other device features from executing as quickly, such as processing packets from a host computer.
The following script took approximately 8.4 µs per iteration when tested:
LJ.setLuaThrottle(10)
local x = 1
for i = 1, 100000 do
x = x + 1
end
The same loop took approximately 10.8 µs per iteration when the LabJack was configured to execute 100 instructions per service interval:
LJ.setLuaThrottle(100)
local x = 1
for i = 1, 100000 do
x = x + 1
end
Benchmark Comparison
There are three ways to toggle a digital I/O line using the LabJack Lua Library functions:
MB.writeName
(a Modbus Name Function)MB.W
(a Modbus Address Function)LJ.DIO_S_W
(a Shortcut Function)
Each of the three methods are shown with benchmark results below. Note that these benchmark tests use local function references.
MB.writeName
- Modbus Name Function
Approximately 24 μs per iteration.
LJ.setLuaThrottle(1000)
local modbus_write_name = MB.writeName
for i = 1, 100000 do
modbus_write_name("FIO5", 1)
end
MB.W
- Modbus Address Function
Approximately 17 μs per iteration.
LJ.setLuaThrottle(1000)
local mbW = MB.W
for i = 1, 100000 do
mbW(2005, 0, 1)
end
LJ.DIO_S_W
- Shortcut Function
Approximately 11 μs per iteration.
LJ.setLuaThrottle(1000)
local dioStateWrite = LJ.DIO_S_W
for i = 1, 100000 do
dioStateWrite(5,1)
end
Comparison with External Communications
Since T-Series devices implement a Modbus Server that can be controlled directly by Lua or by a host computer, the performance of these functions can be useful to compare to round trip command-response times issued by host computers through the USB, Ethernet, or WiFi communication interfaces.