Ark
Ark copied to clipboard
Small number optimization in bytecode
(let i 0) (print i)
in ArkScript generates the following bytecode
Version: 3.0.15
Timestamp: 1620651845
SHA256: eb4587372d295f8db6314323142f64d46961f38f4d0d07f2c259710b45043
Symbols table (length: 1)
0) i
Constants table (length: 1)
0) (Number) 0.000000
Code segment 0 (length: 16)
0 LOAD_CONST (Number) 0.000000
3 LET i
6 LOAD_SYMBOL i
9 BUILTIN print
12 CALL (1)
15 HALT
We're not interested in the print itself, I added it to avoid dealing with the optimizer (which would have optimized away the variable and generated an empty bytecode file), we are interested in the LOAD_CONST (Number) 0.000000
. It's taking 1 byte for the instruction and 2 more for the index of the constant, thus 3 bytes to load a constant from a space somewhere in memory, push it on a stack, and later pop it and store it in i
.
The whole thing is just loading the constant table and then searching it for a specific one (this is O(1) because the table is contiguous and we have the constant's id) is pretty heavy for such a small value. So much work for a 0.
Proposal
What I'm suggesting now, is introducing a special instruction, fused with a number. Since instructions are on 1 byte, we have 1 bit for the instruction and 7 free bits for the number (from 0 to 127).
Limitations
We are limited to numbers between 0 and 127, the other will have to be kept in the constant table as before. Though we could change our interpretation to store numbers between -64 and 63 so that common negative numbers can use this optimization (eg -1 and -2).
Also this is drastically limiting the number of instructions we can have, from 256 to 128, I don't think we will suffer from this, since we only have 44 different instructions currently. If this is considered as a loss, we can agree on something less aggresive, such as LOAD_SMALL_NUM <number on 1 byte, maybe 2>
Summary
Idea 1
Add a special instruction LOAD_SMALL_NUM
, with value 0x80 (0b1000'0000), with its argument being located on its low bits.
Idea 2-1
Add a new instruction LOAD_SMALL_NUM
, taking a 1 byte number (between -128 and 127).
Idea 2-2
Add a new instruction LOAD_SMALL_NUM
, taking a 2 bytes number (between -32768 and 32767).