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.7050
2) 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