I am glad that you like this post and I hope that you like the next three in
this series.
There is a performance difference. Formally, the for loop is
for(expr1; expr2; expr3)
and expr2 is evaluated at each iteration of the loop.
i<=r
is faster to evaluate than
i<=rows(X)
In code block 1 is some code that illustrates this difference. On my machine, myfor2(1e7) took about twice as long as myfor1(1e7).
----------- Begin Code block 1-------------------
clear all
mata:
void myfor1(real scalar limit)
{
real scalar i, j
for(i=0; i<=limit; i++) {
j=1
}
}
real scalar fofx(real scalar x)
{
return(x)
}
void myfor2(real scalar limit) {
real scalar i, j, r
for(i=0; i<=fofx(limit); i++) {
j=1
}
}
myfor1(10)
myfor2(10)
timer_clear()
timer_on(1)
myfor1(1e7)
timer_off(1)
timer_on(2)
myfor2(1e7)
timer_off(2)
timer()
end
----------- End Code block 1-------------------
Bill Gould discusses how for uses expressions in section 4.2.3.2 of
his new book The Mata Book: A Book for Serious Programmers and
Those Who Want to Be. (Go to https://www.stata.com/books... for more information.)
Now, I answer your question about how Mata cleans up its objects.
Mata automatically cleans up objects that are local to functions. Objects
placed in global Mata memory are not automatically cleaned up.
Here is some code that illustrates these points.
clear all
mata:
void dowork(real scalar p) {
real scalar X
X = J(p, p, 4)
}
end
program define usemata1
mata: b = J(3, 3, 4)
display "What Mata has before dowork()"
mata: mata describe
mata: dowork(3)
mata: mata describe
display "What Mata has after dowork()"
end
usemata1
display "What Mata has after usemata1"
mata: mata describe
I hope that the above discussions are useful.
David M. Drukker