performance problem with complex

  • From: Laurent Deniau <Laurent.Deniau@xxxxxxx>
  • To: "luajit@xxxxxxxxxxxxx" <luajit@xxxxxxxxxxxxx>
  • Date: Mon, 9 May 2016 08:11:10 +0000

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

Other related posts: