Hey all! I have just picked up Julia as a fun language to learn and have been translating old python code both as a learning experience and to see just how much performance i can squeeze out of it. I think I have gotten all i can from just reading the performance tips, and thought it would be really beneficial to have some veteran eyes show me the way. If it is not too much to ask I am going to post some code snippets and see what can be done. These functions will be run thousands of times each so I’m looking to learn how to squeeze every last bit of speedup out of them. Any array used should be a 1D array with 10^6 → 10^8 elements. The signal varies from white noise to sinusoidal behavior. Thanks in advance for any cool tips or feedback!
# The data i have been using for benchmarking purposes
t = LinRange(0,10^5,10^7)
signal = 3sin.(2π*8*t) .+ sin.(2π*4*t) + .03*randn(length(t))
d = [11, 111, 1111, 11111]
"Pad an array by mirroring the endpoints"
function mirror(A,d::Int=3)
w = div(d-1,2) #width of window, d is an ODD integer
output = zeros(length(A)+2w)
output[w+1:end-w] = vec(A) #center signal
output[1:w] = reverse!(view(A,2:w+1))
output[end-w:end]= reverse!(view(A,lastindex(A)-w-1:lastindex(A)-1))
return output
end
"""
Fast Implementation of a minmax order statistics filter. Computes the upper and
lower envelopes of a signal.
"""
function stream_minmax!(env1::Array{Float64},env2::Array{Float64},a,w::Int64)
upper = Int[] #buffer for indices
lower = Int[]
pushfirst!(upper,1)
pushfirst!(lower,1)
for i in 2:lastindex(a)
if i >= w
@views env1[i] = a[upper[1]]
@views env2[i] = a[lower[1]]
end
if a[i] > a[i-1]
pop!(upper)
# remove maxima from buffer that are less than our new one
while isempty(upper) != true && a[i] > a[upper[end]]
pop!(upper)
end
elseif a[i] <= a[i-1]
pop!(lower)
# remove minima from buffer that are greater than our new one
while isempty(lower) != true && a[i] < a[lower[end]]
pop!(lower)
end
end
push!(upper,i)
push!(lower,i)
if i == w + upper[1]
popfirst!(upper)
elseif i == w + lower[1]
popfirst!(lower)
end
end
nothing
end
"Moving average with window size d"
function moving_average(A,d::Int=3)
ret = zeros(length(A))
cumsum!(ret,A)
ret = (ret[d+1:end] .- ret[1:end-d]) / d
return ret
end