These tests test the allocation performance of 3 passback variable options and the subsequent access time when retrieving the value back from the calling function.
The difficulty in a general solution arises with void safety. CELL needs to have an initial value provided upon creation, for a complex type a dummy value may not be an option so a detachable type would be used with the default value initialized to void. TUPLE isn't currently void-safe though in the future the thinking is that TUPLE will need default initialization similar to CELL. The performance hit would then be on the retrieval needing to go through an object test. SPECIAL has the unique property of being able to have an attached type without an initializer. Note there are 10x more retrieval attempts than allocations in order to get a descent time sample; allocation is by far the slower process.
Test setup:
- ES version 6.5.8.1550
- Finalized
- Complete void-safety
- Types attached by default
Results:test_1 CELL allocation: 21.259, 21.159, 21.206
test_2 TUPLE allocation:24.490, 24.483, 24.514
test_3 SPECIAL allocation:22.502, 22.515, 22.553
test_4 CELL access:10.613, 10.571, 10.572
test_5 TUPLE access:12.901, 12.841, 12.837
test_6 SPECIAL access:13.642, 13.572, 13.580
test_7 CELL access no object test:10.614, 10.590, 10.584
Allocation (greater is faster)CELL > SPECIAL > TUPLE
Access (greater is faster)CELL > TUPLE > SPECIAL
Allocation time is a factor of 20 slower than access so over all CELL is the fastest when used as a single creation single passback context. All of these options are very close in performance to each other and realistically shouldn't make a difference.
It's unusual that SPECIAL would have a slower access time than an object check with CELL or TUPLE.
feature
make
do
test_1
end
test_1
local
i: INTEGER
do
from
i := 0
until
i > 100_000_000
loop
test_cell
i := i + 1
end
end
test_2
local
i: INTEGER
do
from
i := 0
until
i > 100_000_000
loop
test_tuple
i := i + 1
end
end
test_3
local
i: INTEGER
do
from
i := 0
until
i > 100_000_000
loop
test_special
i := i + 1
end
end
test_4
local
r0: CELL [detachable CELL [NATURAL_32]]
r1: CELL [detachable CELL [NATURAL_32]]
i: INTEGER
val: detachable CELL [NATURAL_32]
val_2: NATURAL_32
do
create r0.put (Void)
create r1.put (Void)
sub_ddmmss_cell (r0, r1, 0x55bf739f, 0xc3945435, 0x0fff167f, 0xf3e8e754)
from
i := 0
until
i > 1_000_000_000
loop
val := r0.item
if attached {CELL [NATURAL_32]} val as val_l then
val_2 := val_l.item
end
val := r1.item
if attached {CELL [NATURAL_32]} val as val_l then
val_2 := val_l.item
end
i := i + 1
end
end
test_5
local
r0: TUPLE [r0: detachable CELL [NATURAL_32]]
r1: TUPLE [r1: detachable CELL [NATURAL_32]]
i: INTEGER
val: detachable CELL [NATURAL_32]
val_2: NATURAL_32
do
create r0
create r1
sub_ddmmss_tuple (r0, r1, 0x55bf739f, 0xc3945435, 0x0fff167f, 0xf3e8e754)
from
i := 0
until
i > 1_000_000_000
loop
val := r0.r0
if attached {CELL [NATURAL_32]} val as val_l then
val_2 := val_l.item
end
val := r1.r1
if attached {CELL [NATURAL_32]} val as val_l then
val_2 := val_l.item
end
i := i + 1
end
end
test_6
local
r0: SPECIAL [CELL [NATURAL_32]]
r1: SPECIAL [CELL [NATURAL_32]]
i: INTEGER
val_2: NATURAL_32
do
create r0.make_empty (1)
create r1.make_empty (1)
sub_ddmmss_special (r0, r1, 0x55bf739f, 0xc3945435, 0x0fff167f, 0xf3e8e754)
from
i := 0
until
i > 1_000_000_000
loop
val_2 := r0 [0].item
val_2 := r1 [0].item
i := i + 1
end
end
test_7
local
r0: CELL [detachable CELL [NATURAL_32]]
r1: CELL [detachable CELL [NATURAL_32]]
i: INTEGER
val: NATURAL_32
do
create r0.put (Void)
create r1.put (Void)
sub_ddmmss_cell (r0, r1, 0x55bf739f, 0xc3945435, 0x0fff167f, 0xf3e8e754)
from
i := 0
until
i > 1_000_000_000
loop
val := r0.item.item
val := r1.item.item
i := i + 1
end
end
test_cell
local
r0: CELL [detachable CELL [NATURAL_32]]
r1: CELL [detachable CELL [NATURAL_32]]
do
create r0.put (Void)
create r1.put (Void)
sub_ddmmss_cell (r0, r1, 0x55bf739f, 0xc3945435, 0x0fff167f, 0xf3e8e754)
end
test_tuple
local
r0: TUPLE [r0: detachable CELL [NATURAL_32]]
r1: TUPLE [r1: detachable CELL [NATURAL_32]]
do
create r0
create r1
sub_ddmmss_tuple (r0, r1, 0x55bf739f, 0xc3945435, 0x0fff167f, 0xf3e8e754)
end
test_special
local
r0: SPECIAL [CELL [NATURAL_32]]
r1: SPECIAL [CELL [NATURAL_32]]
do
create r0.make_empty (1)
create r1.make_empty (1)
sub_ddmmss_special (r0, r1, 0x55bf739f, 0xc3945435, 0x0fff167f, 0xf3e8e754)
end
sub_ddmmss_cell (sh: CELL [detachable CELL [NATURAL_32]]; sl: CELL [detachable CELL [NATURAL_32]]; ah: NATURAL_32; al: NATURAL_32; bh: NATURAL_32; bl: NATURAL_32)
local
x: NATURAL_32
do
x := al - bl
sh.put (create {CELL [NATURAL_32]}.put (ah - bh - (al < bl).to_integer.to_natural_32))
sl.put (create {CELL [NATURAL_32]}.put (x))
end
sub_ddmmss_tuple (sh: TUPLE [sh: detachable CELL [NATURAL_32]]; sl: TUPLE [sl: detachable CELL [NATURAL_32]]; ah: NATURAL_32; al: NATURAL_32; bh: NATURAL_32; bl: NATURAL_32)
local
x: NATURAL_32
do
x := al - bl
sh.sh := create {CELL [NATURAL_32]}.put (ah - bh - (al < bl).to_integer.to_natural_32)
sl.sl := create {CELL [NATURAL_32]}.put (x)
end
sub_ddmmss_special (sh: SPECIAL [CELL [NATURAL_32]]; sl: SPECIAL [CELL [NATURAL_32]]; ah: NATURAL_32; al: NATURAL_32; bh: NATURAL_32; bl: NATURAL_32)
local
x: NATURAL_32
do
x := al - bl
sh.force (create {CELL [NATURAL_32]}.put (ah - bh - (al < bl).to_integer.to_natural_32), 0)
sl.force (create {CELL [NATURAL_32]}.put (x), 0)
end
Update: Replaced extend' in special test with more realistic
force'. This makes CELL with an object test the fastest option.
Update: Added test_7 which tests accessing cell without an object test. This compared to test_4 with an object test shows object tests are negligible performance hits when the test always is true.