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 <[email protected]> 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, <[email protected]> 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 ([email protected])
