Ben Jann wrote:
Hi, I have an expression such as
y = x :* k
in my Mata code, where x is vector and k is a vector or a scalar
depending on context. I am now wondering whether it is reasonable to
avoid using the colon operator in cases where k is a scalar and, e.g.,
code
if (length(k)==1) y = x * k
else y = x :* k
I did some speed tests and they are indicating that using the second
solution will be considerably faster in case of k being scalar. Here is
an example:
. mata: x = uniform(10000,1)
r; t=0.00 15:08:55
. mata: for (i=1;i<=10000;i++) y = x*1
r; t=2.20 15:08:57
. mata: for (i=1;i<=10000;i++) y = x:*1
r; t=4.80 15:09:02
Can anyone confirm these results? Is it true that the colon operator
significantly slows down computations if used in situations where it is
not really needed or is this just an artifact produced by my local
machine?
--------------------------------------------------------------------------------
The pattern looks similar on my (much slower) machine. And you don't take
much of a penalty by performing the -if ... else-. So, it seems to make
sense in your case.
Joseph Coveney
. forvalues i = 1/5 {
2. display in smcl as result `i', `cumulator`i''
3. }
1 63.19
2 33.35
3 63.39
4 33.65
5 33.85
. exit
-------------------
version 9.2
mata
mata clear
mata set matastrict on
void function timem1()
{
real scalar i, k
real colvector x, y
x = uniform(10000, 1)
for (i = 1; (i <= 10000); i++) y = x :* 1;
}
void function timem2()
{
real scalar i
real colvector x, y
x = uniform(10000, 1)
for (i = 1; (i <= 10000); i++) y = x * 1;
}
void function timem3()
{
real scalar i
real colvector x
real rowvector y
x = uniform(10000, 1)
for (i = 1; (i <= 10000); i++) y = (x :* 1)';
}
void function timem4()
{
real scalar i
real colvector x
real rowvector y
x = uniform(10000, 1)
for (i = 1; (i <= 10000); i++) y = (x * 1)';
}
void function timem5()
{
real scalar i, k
real colvector x, y
k = floor(2 * uniform(1, 1)) + 1
x = uniform(10000, 1)
for (i = 1; (i <= 10000); i++) {
if (length(k) == 1) y = x * k
else y = x :* k
}
}
end
set more off
set seed `= date("2006-05-21", "ymd")'
forvalues i = 1/5 {
local cumulator`i' = 0
}
forvalues i = 1/10 {
forvalues j = 1/5 {
timer clear `j'
timer on `j'
mata: timem`j'()
timer off `j'
timer list `j'
local cumulator`j' = `cumulator`j'' + r(t`j')
}
}
forvalues i = 1/5 {
display in smcl as result `i', `cumulator`i''
}
exit
-----------
*
* For searches and help try:
* http://www.stata.com/support/faqs/res/findit.html
* http://www.stata.com/support/statalist/faq
* http://www.ats.ucla.edu/stat/stata/