Performance considerations CALLNAT vs. internal Subroutine vs. Function

Hello all,

of course I expected that CALLNAT is slower than an internal Sub. But I never thought that the difference is that big:

My test:

``````define data local
01 #loops (I4) const <1000000>
01 #a  (A) dynamic init <'foo   '>
01 #i4 (I4)
01 #timx (T)
end-define
*
define prototype #trim1
returns (A) dynamic
define data parameter
1 #A     (A) dynamic by value
end-define
end-prototype
*
#timx := *TIMX
for #i4 = 1 to #loops
reset initial #a
#a := *TRIM(#a)
end-for
#timx := *TIMX - #timx
write #TIMX (EM=II:SS.T) 'trim'
*
#timx := *TIMX
for #i4 = 1 to #loops
reset initial #a
perform trim1
end-for
#timx := *TIMX - #timx
write #TIMX (EM=II:SS.T) 'internal sub'
*
#timx := *TIMX
for #i4 = 1 to #loops
reset initial #a
callnat 'trim1n' #a
end-for
#timx := *TIMX - #timx
write #TIMX (EM=II:SS.T) 'callnat'
*
#timx := *TIMX
for #i4 = 1 to #loops
reset initial #a
#a := #trim(<#a>)
end-for
#timx := *TIMX - #timx
write #TIMX (EM=II:SS.T) 'func'
*
define subroutine trim1
#a := *TRIM(#a)
end-subroutine
end``````

while tim1n is:

``````define data parameter
1 #a (A) dynamic
end-define
#a := *TRIM(#a)
end``````

and trim17 is:

``````define function #trim
returns (A) dynamic
define data parameter
1 #a (A) dynamic
end-define
#trim := *TRIM(#a)
end-function
end``````

Result:

00:02.2 trim
00:02.6 internal sub
00:26.3 callnat
00:27.5 func

And defining a prototype or not doesn’t have any influence on runtime.

Some other runtimes:

00:30.2 callnat by val
00:29.7 func by val
00:24.4 external sub
02:39.2 multi purpose func with parameter (i.e. #a := #adump(<#a,‘mdb’>) )

Hi Matthias;

Actually, it is worse than you might think.