Dear All,
I found that the primary cdata type ‘complex’ is not well optimised by the JIT
in some aspects.
The timing of the code hereafter on my laptop is about 6.5 sec. If in the code
below you (exclusively):
- replace complex(0,1) by 1i, the timing becomes 3.5 sec, I guess because the
constant complex number is a created by the lexer directly and reused (cloned).
- uncomment the definition of the __new metamethod that allows to replace the
primary cdata type by a simple table and adjust the init and the test in the
iterator, the timing becomes 0.05 sec.
So tables improves the speed by a factor 130 (!) despite that complex is a
read-only primary cdata type, i.e. I would expect better performance for
complex than for generic table. I suspect that it is the sink optimisation
which does not apply to complex cdata because the computation in the loop are
about the same when the table and complex are created outside the loop, and
well optimised.
Any hint to improve this aspect of the primary complex cdata type? Because
constant like 1i creates a cdata type in any case (done at the lexer level)
which is a killer in formula with constant imaginary numbers.
Best,
Laurent.
local ffi = require 'ffi'
local complex = ffi.typeof 'complex'
local M={}
-- M.__new = function (ct, re, im)
-- return setmetatable({re,im}, M)
-- end
M.__index = M
local function iter(r, i)
if i < 1 then -- for cdata
-- if i < 2 then -- for tables
return i+1, r[i+1]
end
end
function M.__ipairs (r)
return iter, r, 0 -- for cdata
-- return iter, r, 1 -- for tables
end
ffi.metatype('complex', M)
local a = 0
for i=1,5e7 do
local r = complex(0,1)
for _,v in ipairs(r) do
a = a + v
end
end
print(a) -- 50000000
--
Laurent Deniau http://cern.ch/mad
Accelerators Beam Physics mad@xxxxxxx<mailto:mad@xxxxxxx>
CERN, CH-1211 Geneva 23 Tel: +41 (0) 22 767 4647