Hi all. I'm developing a function, which must return a square matrix. Here is the code: http://pastebin.com/THzEW9N7 These functions implement an analog of two embedded for cycles. The first variant creates the resulting matrix by columns, cbind()-ing them one by one. The second variant creates the matrix with two columns, which rows contain all possible variants of i and j and calls apply on them. The test input (data frame cp.table) can be produced with the following commands:> n<-132 > cpt<-data.frame(x=runif(n, min=0, max=100), y=runif(n, min=0, max=100), > la=runif(n, min=0, max=360), phi=runif(n, min=-90, max=90))Any random data will do. The second variant seems to me much more readable and beauteful. However, the first ugly variant runs much faster. Why?? Here are the profiles: -- View this message in context: http://r.789695.n4.nabble.com/More-simple-implementation-is-slow-tp4632872.html Sent from the R help mailing list archive at Nabble.com.
On Jun 9, 2012, at 11:08 , wl2776 wrote:> Hi all. > I'm developing a function, which must return a square matrix. > > Here is the code: > http://pastebin.com/THzEW9N7 > > These functions implement an analog of two embedded for cycles. > > The first variant creates the resulting matrix by columns, cbind()-ing them > one by one. > The second variant creates the matrix with two columns, which rows contain > all possible > variants of i and j and calls apply on them. > > The test input (data frame cp.table) can be produced with the following > commands: >> n<-132 >> cpt<-data.frame(x=runif(n, min=0, max=100), y=runif(n, min=0, max=100), >> la=runif(n, min=0, max=360), phi=runif(n, min=-90, max=90)) > Any random data will do. > > The second variant seems to me much more readable and beauteful. > However, the first ugly variant runs much faster. > Why?? > Here are the profiles: >Nope, they weren't... Anyways, you're effectively looping over N^2 (i,j) combinations, with complex indexing all the way, without making proper use of vectorization. As far as I can tell, what you're doing is effectively with(cp.table, sqrt(outer(x, x, "-")^2 + outer(y, y, "-")^2) ) or even dist(cptable[1:2]) both of which should be a good deal faster. -- Peter Dalgaard, Professor, Center for Statistics, Copenhagen Business School Solbjerg Plads 3, 2000 Frederiksberg, Denmark Phone: (+45)38153501 Email: pd.mes at cbs.dk Priv: PDalgd at gmail.com
I've created another get_tau implementation, using sapply and apply. http://pastebin.com/3FaHAL1i However, the second variant, with expand.grid still appeals me most. I don't undestand, why it is so slow. -- View this message in context: http://r.789695.n4.nabble.com/More-simple-implementation-is-slow-tp4632872p4632879.html Sent from the R help mailing list archive at Nabble.com.
Sorry, here are the profiles:
summaryRprof("get_tau")
$by.self
self.time self.pct total.time total.pct
"cbind" 0.02 50 0.04 100
"unlist" 0.02 50 0.02 50
$by.total
total.time total.pct self.time self.pct
"cbind" 0.04 100 0.02 50
"get_tau" 0.04 100 0.00 0
"unlist" 0.02 50 0.02 50
"apply" 0.02 50 0.00 0
$sample.interval
[1] 0.02
$sampling.time
[1] 0.04
summaryRprof("get_tau2")
$by.self
self.time self.pct total.time total.pct
"FUN" 0.48 51.06 0.84 89.36
"$" 0.34 36.17 0.34 36.17
"ls" 0.08 8.51 0.08 8.51
"+" 0.02 2.13 0.02 2.13
"lapply" 0.02 2.13 0.02 2.13
$by.total
total.time total.pct self.time self.pct
"apply" 0.86 91.49 0.00 0.00
"get_tau2" 0.86 91.49 0.00 0.00
"FUN" 0.84 89.36 0.48 51.06
"$" 0.34 36.17 0.34 36.17
"ls" 0.08 8.51 0.08 8.51
"apropos" 0.08 8.51 0.00 0.00
".completeToken" 0.08 8.51 0.00 0.00
"normalCompletions" 0.08 8.51 0.00 0.00
"+" 0.02 2.13 0.02 2.13
"lapply" 0.02 2.13 0.02 2.13
"unlist" 0.02 2.13 0.00 0.00
$sample.interval
[1] 0.02
$sampling.time
[1] 0.94
I also was advised to use
with(cpt, sqrt(outer(x, x, "-")^2 + outer(y, y, "-")^2)
)
And here is its profile
summaryRprof("with")
$by.self
self.time self.pct total.time total.pct
"gsub" 0.02 100 0.02 100
$by.total
total.time total.pct self.time self.pct
"gsub" 0.02 100 0.02 100
".completeToken" 0.02 100 0.00 0
"grep" 0.02 100 0.00 0
"keywordCompletions" 0.02 100 0.00 0
"makeRegexpSafe" 0.02 100 0.00 0
"normalCompletions" 0.02 100 0.00 0
"sprintf" 0.02 100 0.00 0
$sample.interval
[1] 0.02
$sampling.time
[1] 0.02
Apparently, it is about twise faster.
--
View this message in context:
http://r.789695.n4.nabble.com/More-simple-implementation-is-slow-tp4632872p4632881.html
Sent from the R help mailing list archive at Nabble.com.