Statalist The Stata Listserver


[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–2014 StataCorp LP   |   Terms of use   |   Privacy   |   Contact us   |   What's new   |   Site index