Skip to content

Instantly share code, notes, and snippets.

@ssfrr
Last active August 29, 2015 14:03
Show Gist options
  • Save ssfrr/8934c14d8d2703a3d203 to your computer and use it in GitHub Desktop.
Save ssfrr/8934c14d8d2703a3d203 to your computer and use it in GitHub Desktop.
Testing per-function-call allocation against re-using buffer in type
type BufContainer
inc_amt::Float32
buf::Array{Float32}
BufContainer(inc_amt) = new(inc_amt, Array(Float32, 1024))
end
function with_alloc(cont::BufContainer)
buf = Array(Float32, 1024)
for i in 1:length(buf)
buf[i] += cont.inc_amt
end
return buf
end
function without_alloc(cont::BufContainer)
for i in 1:length(cont.buf)
cont.buf[i] += cont.inc_amt
end
return cont.buf
end
function without_alloc_with_temp(cont::BufContainer)
temp = cont.buf
for i in 1:length(temp)
temp[i] += cont.inc_amt
end
return temp
end
function using_parameter(cont::BufContainer, buf::Array{Float32})
for i in 1:length(buf)
buf[i] += cont.inc_amt
end
return buf
end
function buftest()
cont = BufContainer(1)
buf = Array(Float32, 1024)
# call once for JITting
_ = with_alloc(cont)
_ = without_alloc(cont)
_ = without_alloc_with_temp(cont)
_ = using_parameter(cont, buf)
N_TRIALS=100000
gc()
println("Doing $N_TRIALS Interations of each...\n-------")
println("Timing with allocation each call")
@time begin
for _ in 1:N_TRIALS
res = with_alloc(cont)
end
gc()
end
println("Timing without allocation each call")
@time begin
for _ in 1:N_TRIALS
res = without_alloc(cont)
end
gc()
end
println("Timing without allocation using a temp buffer each call")
@time begin
for _ in 1:N_TRIALS
res = without_alloc_with_temp(cont)
end
gc()
end
println("Timing passing array as a parameter")
@time begin
for _ in 1:N_TRIALS
res = using_parameter(cont, cont.buf)
end
gc()
end
end
buftest()
# run on 1.6GHz i5
# Doing 100000 Interations of each...
# -------
# Timing with allocation each call
# elapsed time: 0.474479476 seconds (417591824 bytes allocated, 42.90% gc time)
# Timing without allocation each call
# elapsed time: 0.35568662 seconds (1591824 bytes allocated, 2.88% gc time)
# Timing without allocation using a temp buffer each call
# elapsed time: 0.18984845 seconds (1591824 bytes allocated, 5.64% gc time)
# Timing passing array as a parameter
# elapsed time: 0.173606393 seconds (1591824 bytes allocated, 6.03% gc time)
@mauro3
Copy link

mauro3 commented Jun 25, 2014

With this code I get:

Timing with allocation each call
elapsed time: 0.001781621 seconds (4167824 bytes allocated)
Timing without allocation each call
elapsed time: 0.001545691 seconds (7824 bytes allocated)
Timing without allocation using a temp buffer each call
elapsed time: 0.00088557 seconds (7824 bytes allocated)
Timing passing array as a parameter
elapsed time: 0.000885131 seconds (7824 bytes allocated)

The difference between 2 & 3 is because of getting the field of cont (I think)

type BufContainer
    inc_amt::Float32
    buf::Array{Float32,1}

    BufContainer(inc_amt) = new(inc_amt, Array(Float32, 1024))
end

function with_alloc(cont::BufContainer)
    buf = Array(Float32, 1024)
    for i in 1:length(buf)
        buf[i] += cont.inc_amt
    end
    return buf
end

function without_alloc!(cont::BufContainer)
    for i in 1:length(cont.buf)
        cont.buf[i] += cont.inc_amt
    end
end

function without_alloc_with_temp!(cont::BufContainer)
    temp = cont.buf
    for i in 1:length(temp)
        temp[i] += cont.inc_amt
    end
end

function using_parameter!(cont::BufContainer, buf)
    for i in 1:length(buf)
        buf[i] += cont.inc_amt
    end
end

cont = BufContainer(1)
buf = Array(Float32, 1024)
# call once for JITting
_ = with_alloc(cont)
_ = without_alloc!(cont)
_ = without_alloc_with_temp!(cont)
_ = using_parameter!(cont, buf)

gc()
println("Timing with allocation each call")
@time for _ in 1:1000
    cont.buf = with_alloc(cont)
end
gc()
println("Timing without allocation each call")
@time for _ in 1:1000
    without_alloc!(cont)
end
gc()
println("Timing without allocation using a temp buffer each call")
@time for _ in 1:1000
    res = without_alloc_with_temp!(cont)
end
gc()
println("Timing passing array as a parameter")
@time for _ in 1:1000
    using_parameter!(cont, buf)
end

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment