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
>>>
>>>
>>>
>>>
>>

Reply via email to