From simon.urbanek at r-project.org  Mon Apr 14 23:11:24 2008
From: simon.urbanek at r-project.org (Simon Urbanek)
Date: Mon, 14 Apr 2008 17:11:24 -0400
Subject: [Rd] HOW TO AVOID LOOPS
In-Reply-To: <004601c89e6d$9e67dd50$6401a8c0@G3>
References: <FC1A822CDEFB4DE38EB135F6BE851F55@your136f2019dc>
	<004601c89e6d$9e67dd50$6401a8c0@G3>
Message-ID: <00598712-C103-448D-92E2-8657A1A0A4AA@r-project.org>


On Apr 14, 2008, at 4:22 PM, Stephen Milborrow wrote:

>> Le sam. 12 avr. ? 12:47, carlos martinez a ?crit :
>> Looking for a simple, effective a minimum execution time solution.
>>
>> For a vector as:
>>
>> c(0,0,1,0,1,1,1,0,0,1,1,0,1,0,1,1,1,1,1,1)
>>
>> To transform it to the following vector without using any loops:
>>
>> (0,0,1,0,1,2,3,0,0,1,2,0,1,0,1,2,3,4,5,6)
>
> Here is a fast solution using the Ra just-in-time compiler
> www.milbo.users.sonic.net/ra.
>
> jit(1)
> if (length(x) > 1)
>   for (i in 2:length(x))
>       if (x[i])
>           x[i] <- x[i-1] + 1
>
> The times in seconds for various solutions mailed to r-devel are  
> listed
> below. There is some variation between runs and with the contents of  
> x. The
> times shown are for
>
> set.seed(1066);  x <- as.double(runif(1e6) > .5)
>
> This was tested on a WinXP 3 GHz Pentium D with Ra 1.0.7 (based on R  
> 2.6.2).
> The code to generate these results is attached.
>

Well, if you want to break the rules, you may as well do it properly ;).

library(inline)
f = cfunction(signature(n="integer", x="numeric"),
"for(int i = 1; i < *n; i++) if (x[i]) x[i] = x[i-1] + 1;",
convention=".C")

f(length(x), x)

inline 0.03s
pure 2.7s
hadley 4.5s

(I couldn't measure Ra reliably - I was getting times around 2s which  
seems inappropriate - Stephen, how did you measure it?).

Cheers,
S




> vin     24
> greg   11
> had    3.9
> dan    1.4
> dan2  1.4
> jit       0.25    # code is shown above, 7 secs with standard R 2.6.2>
>
> Stephen Milborrow
> www.milbo.users.sonic.net
> <cm-post.R.txt>______________________________________________
> R-devel at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel



[Rd] HOW TO AVOID LOOPS
Simon Urbanek