In theory, the compiler could potentially pull the bounds check out of the loop since the loop parameters are run-time constants, which means that the bounds check doesn't actually need to happen on each access.
-- John On Aug 29, 2014, at 1:21 PM, Ed Scheinerman <edward.scheiner...@gmail.com> wrote: > The compiler can't know how far I will traverse the array. That's passed in > as an argument. I've run this short of the end (and past the end) and timings > are always the same. > > On Friday, August 29, 2014, Johan Sigfrids <johan.sigfr...@gmail.com> wrote: > I believe that for simple cases the compiler is smart enough to remove bound > checking on its own. In that case adding @inbounds won't help. > > On Friday, August 29, 2014 8:03:35 PM UTC+3, Ed Scheinerman wrote: > I'd like to use @inbounds also to speed up code that I'm 100% sure has proper > array indices. But I tried the following experiment and found no significant > difference using or omitting @inbounds before the array access. What am I > doing wrong? Or is bounds checking so super efficient that I shouldn't worry > about it. > > Here's the code: > > function filler(data::Array{Int,1}, n::Int, reps::Int=1000) > tic() > for r=1:reps > for k=1:n > data[k]=k > end > end > toc() > end > > > function fast_filler(data::Array{Int,1},n::Int, reps::Int=1000) > tic() > for r=1:reps > for k=1:n > @inbounds data[k]=k > end > end > toc() > end > > n = 10*1000*1000 # 10 million > x = zeros(Int,n) > filler(x,n,1000) > fast_filler(x,n,1000) > > Here's the output: > > elapsed time: 12.622814907 seconds > elapsed time: 12.287447772 seconds > > > > > On Monday, August 4, 2014 1:56:51 PM UTC-4, Jacob Quinn wrote: > Steve, > > `@inbounds` is certainly tricky because of the lack of documentation, which I > think is slightly on purpose as this is meant to be for more advanced usage. > > The main insight to using `@inbounds` correctly is realizing that `@inbounds > expression` returns the value `nothing`. That's why your first two examples > don't seem to work. The value is indeed being calculated with bounds checking > off, but you're not assigning the value anywhere, so `nothing` is the result > of the expression. You can also do multi-line turning off of bounds checking > by using a `begin...end` block. > > Try the following: > > function sqrtfirst{T}(a::Array{T, 1}) > @assert(size(a,1) >= 1) > @inbounds ans = sqrt(a[1]) > return ans > end > > function sqrtfirst{T}(a::Array{T, 1}) > @assert(size(a,1) >= 1) > @inbounds begin > # do several getindex, setindex! operations > end > return ans > end > > Hope that helps! > > -Jacob > > > On Mon, Aug 4, 2014 at 1:45 PM, <vav...@uwaterloo.ca> wrote: > Dear Julia users, > > The usage of the @inbounds macro is not explained the manual, and its syntax > appears to be strange. Consider the three functions at the end of this > posting. Only the third one works -- why? > > In general, I think @inbounds is broken. Besides the weird syntax, it has > two other issues. First, there is no way to apply the macro to one subscript > operation but not another in a long expression (as far as I know). Second, > it is not extensible in the sense that if programmer A implements his/her own > array-like structure with his/her own getindex and setindex operations, > he/she might like to have two versions of getindex/setindex, one safe/slower > and the other unsafe/faster, but there is no way for programmer A to detect > whether user B, a user of his/her new array-like structure, has requested > @inbounds or not. > > I would like to propose the following replacement for @inbounds, which solves > all three problems. Instead of a macro, there should be two different > subscript operations, say a[1] and a[$ 1 $], where the first is safe/slow and > the second is unsafe/fast. The compiler will compile the first as > getindex/setindex and the second as getindexUnsafe/setindexUnsafe. > > -- Steve Vavasis > > > > function sqrtfirst{T}(a::Array{T, 1}) > @assert(size(a,1) >= 1) > @inbounds sqrt(a[1]) > end > > function sqrtfirst{T}(a::Array{T, 1}) > @assert(size(a,1) >= 1) > return @inbounds sqrt(a[1]) > end > > function sqrtfirst{T}(a::Array{T, 1}) > @assert(size(a,1) >= 1) > @inbounds return sqrt(a[1]) > end > > > > > > > -- > Ed Scheinerman (e...@scheinerman.net)