When does @inbounds increase performance?

leespen1
Sat, 14 Dec 2024 00:16:10 +0000
Performance

I am interested in making some optimizations in my software. I noticed many packages make use of the @inbounds macro, and the Julia manual mentions @inbounds in its performance tips section (Performance Tips · The Julia Language).

Before going through the effort of adding @inbounds to my code, I decided to write a script to test how much of an effect @inbounds has on performance:

using BenchmarkTools

function add_one!(x)
    for i in 1:length(x)
        x[i] += 1
    end
end

function add_one_inbounds!(x)
    for i in 1:length(x)
        @inbounds x[i] += 1
    end
end

function main()
    x = rand(1_000_000)
    println("Time taken for non-inbounds version:")
    @btime add_one!($x)
    println("\nTime taken for inbounds version:")
    @btime add_one_inbounds!($x)
end

main()

This is the output I got from running the script:

Time taken for non-inbounds version:
  92.003 μs (0 allocations: 0 bytes)

Time taken for inbounds version:
  91.842 μs (0 allocations: 0 bytes)

The speedup is negligible, and when running the script again I sometimes even get that the inbounds version takes longer than the non-inbounds version.

So overall, it seems to me that there is no noticeable speedup, certainly not enough speedup to make me want to risk uncaught memory errors by using @inbounds, even in applications where performance is critical. And in this case, the amount of work being done per index-check is minimal, I am just adding an integer. In real applications I would probably be doing several FLOPs before accessing an array.

So why do people use @inbounds? Is my test flawed, and performance gains are actually much higher in realistic applications? Could someone provide a minimal example where using @inbounds noticeably increases performance?

15 posts - 10 participants