[Date Prev][Date Next][Thread Prev][Thread Next][Date index][Thread index]

# Re: st: Mata slow?

 From wgould@stata.com (William Gould, Stata) To statalist@hsphsun2.harvard.edu Subject Re: st: Mata slow? Date Mon, 27 Nov 2006 09:04:09 -0600

```Brendan Halpin <brendan.halpin@ul.ie> asked about speeding up the Mata code
to perform

for (i=2; i<=length(s1) + 1; i++) {
for (j=2; j<=length(s2) + 1; j++) {
D[i, j] = min((D[i,   j-1] + A[i, j],
D[i-1, j  ] + B[i, j],
D[i-1, j-1] + C[i, j] ));
}
}

and he asked if there was a way to time-profile Mata code.

Concerning the latter, see -help mata timer()-.

Concerning the former, I succeeded in reducing the run time by 49%.

I started with the following do-file:

------------------------------------------- time.do --------
clear

local N 100

mata:

void tryit()
{
timer_clear()                 // clear timers

A = B = C = D = J(`N'+1, `N'+1, 0)
s1 = s2 = J(`N', 1, 0)

timer_on(1)                  // start timer 1
for (i=2; i<=length(s1)+1; i++) {
for (j=2; j<=length(s2)+1; j++) {
D[i,j] = min((D[i,   j-1] + A[i,j],
D[i-1, j  ] + B[i,j],
D[i-1, j-1] + C[i,j]))
}
}
timer_off(1)                 // stop timer 1
timer(1)                     // report timer 1
}

tryit()
end
------------------------------------------- time.do --------

I then decided one timing did not produce stable enough results and
changed the code to read:

------------------------------------------- time.do --------
clear

local N 100

mata:

void tryit()
{
timer_clear()                 // clear timers

A = B = C = D = J(`N'+1, `N'+1, 0)
s1 = s2 = J(`N', 1, 0)

for (k=1; k<=50; k++)
timer_on(1)           // start timer 1
for (i=2; i<=length(s1)+1; i++) {
for (j=2; j<=length(s2)+1; j++) {
D[i,j] = min((D[i,   j-1] + A[i,j],
D[i-1, j  ] + B[i,j],
D[i-1, j-1] + C[i,j]))
}
}
timer_off(1)         // stop timer 1
}
timer(1)                     // report timer 1
}

tryit()
end
------------------------------------------- time.do --------

timer(1) reported a run time for 50 iterations of 1.95 seconds and thus
.03906 seconds per iteration.

I then set about playing to speed up the loop.  My final version of time.do
read,

------------------------------------------- time.do --------
clear

local N 100

mata:

void tryit()
{
timer_clear()                 // clear timers

A = B = C = D = J(`N'+1, `N'+1, 0)
s1 = s2 = J(`N', 1, 0)

for (k=1; k<=50; k++)
timer_on(1)           // start timer 1
n1 = length(s1) + 1
n2 = length(s2) + 1
for (i=2; i<=length(s1)+1; i++) {
i1 = i-1
for (j=2; j<=length(s2)+1; j++) {
j1 = j-1
a = D[ i, j1] + A[i,j]
b = D[i1,  j] + A[i,j]
c = D[i1, j1] + A[i,j]
D[i,j] = (a<b ? (a<c ? a : c) :
(b<c ? b : c))
}
}
timer_off(1)         // stop timer 1
}
timer(1)                     // report timer 1
}

tryit()
end
------------------------------------------- time.do --------

Run time for 50 interations fell from 1.95 to 1.14 seconds.

-- Bill
wgould@stata.com
*
*   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/
```

 © Copyright 1996–2015 StataCorp LP   |   Terms of use   |   Privacy   |   Contact us   |   What's new   |   Site index