I was toying around today with measuring the speed of different forms of loops. Then I realised that if I go for the -while- style of loop, I can do everything that is done with locals, but using only scalars instead of locals.
I think this Stata feature is not documented anywhere in the Stata literature, and I have never seen it applied anywhere. As far as I can see this approach does not seem to have any disadvantages, and has pedagogical value. I had headache getting in the beginning what is this thing in Stata called a "local", then I had headache explaining to students what is this thing called "local" when I was teaching Stata to others. Mostly not because local is a complicated thing, but rather because StataCorp invented it, and it is alien when you hear of it first time. On the other hand everybody knows what is a scalar, no need for much explaining here.
Here is a simple example, we are calculating the sum of the observations in a variable, while pretending we don't know of the -gen,sum()-, -egen, mean()- and the command -summarize- existence.
Code:
clear
set obs 1000000
gen x = rnormal()
timer clear
timer on 1 // Standard Forvalues loop.
sca Ans = 0
qui forvalues i = 1/`=_N' {
sca Ans = Ans + x[`i']
}
dis Ans
timer off 1
timer on 2 // Standard While loop but with decrementation.
sca Ans = 0
local i = _N
qui while `i'>0 {
sca Ans = Ans + x[`i']
local --i
}
dis Ans
timer off 2
timer on 3 // Standard While loop but with incrementation.
sca Ans = 0
local i = 1
qui while `i'<=`=_N' {
sca Ans = Ans + x[`i']
local ++i
}
dis Ans
timer off 3
timer on 4 // While loop using only scalars, decrementation.
sca Ans = 0
sca I = _N
qui while I>0 {
sca Ans = Ans + x[I]
sca I = I - 1
}
dis Ans
timer off 4
timer on 5 // While loop using only scalars, incrementation.
sca Ans = 0
sca I = 1
sca N = _N
qui while I<=N {
sca Ans = Ans + x[I]
sca I = I +1
}
dis Ans
timer off 5
timer list
* They all give the same answer and the timings are:
. timer list
1: 5.79 / 1 = 5.7880
2: 7.97 / 1 = 7.9660
3: 9.60 / 1 = 9.6040
4: 8.21 / 1 = 8.2060
5: 8.71 / 1 = 8.70502) Unexpectedly, the decrementation -while- loops are somewhat faster than the incrementation -while- loops. Does anybody know why is that?
3) The scalar loops seem to be doing fine. There is no loss of speed of execution from moving from -while- with locals to -while- with scalars.
0 Response to Fun Stata fact: You can use scalars instead of locals in while loops, without speed losses in execution.
Post a Comment