Detect if constant

This code and result demonstrates why being able to branch on whether something is known to be a constant is of such value:

Code
using StaticArrays, BenchmarkTools, Plots

function myfunc(::Val{n}) where n
    m = 2 ^ n
    V = rand(SVector{m})
    return V' * V
end

function myfunc(n)
    m = 2 ^ n
    V = rand(m)
    return V' * V
end

const topend = 9
function timeit()
    times = zeros(topend, 3)
    times[1, 1] = @belapsed myfunc(Val(1))
    times[2, 1] = @belapsed myfunc(Val(2))
    times[3, 1] = @belapsed myfunc(Val(3))
    times[4, 1] = @belapsed myfunc(Val(4))
    times[5, 1] = @belapsed myfunc(Val(5))
    times[6, 1] = @belapsed myfunc(Val(6))
    times[7, 1] = @belapsed myfunc(Val(7))
    times[8, 1] = @belapsed myfunc(Val(8))
    times[9, 1] = @belapsed myfunc(Val(9))
    for a = 1:topend
        times[a, 2] = @belapsed myfunc(Val($a))
        times[a, 3] = @belapsed myfunc($a)
    end
    return times
end

times = timeit()
plot(2 .^ (1:topend), times .* 10e6, xlabel="Length of vector", ylabel="Function time (ms)", label=["SVector w. static dispatch" "SVector w. dynamic dispatch" "Vector"], xscale=:log10, yscale=:log10)

What it shows is that if I know that vector length is constant, I can get significant speedups by using SVector instead of Vector, up to a certain length. However, if the vector length is not constant, then the penalty incurred by dynamic dispatch negates all speed advantages of SVector, making it slower than Vector for all lengths.

It is not currently possible to exploit this fact to speed up some code without also risking slowing down the same code under different conditions, because, from what has been said here, I understand it isn’t possible to detect if a value is constant at runtime. This looks like it would be a useful feature.

2 Likes