Skip to content

Instantly share code, notes, and snippets.

@davidagold
Created July 25, 2015 19:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save davidagold/39c59aa0965af1270af4 to your computer and use it in GitHub Desktop.
Save davidagold/39c59aa0965af1270af4 to your computer and use it in GitHub Desktop.
`NullityIndex` -- indexing non-empty entries of a `NullableArray`
immutable NullityIndex
non_nulls::Vector{Int}
end
function NullityIndex(X::NullableArray)
inds = Vector{Int}()
sizehint!(inds, length(X.isnull))
for i in eachindex(X.isnull)
!X.isnull[i] && push!(inds, i)
end
return NullityIndex(inds)
end
# test that 'NullityIndex'es cover all and only the non-null indices of a
# `NullableArray` -- returns `true` if success.
function test(X::NullableArray)
ni = NullityIndex(X)
res = true
for i in ni.non_nulls
res &= !X.isnull[i]
end
for i in setdiff(eachindex(X.isnull), ni.non_nulls)
res &= X.isnull[i]
end
return res
end
function f(tup::Tuple{NullableArray, NullityIndex})
X, ni = tup
res = Nullable(0.0)
for i in ni.non_nulls
@inbounds res += X[i]
end
return res
end
function g(X::NullableArray)
res = Nullable(0.0)
for i in eachindex(X)
@inbounds !X.isnull[i] && (res += X[i])
end
return res
end
function profile(N::Int)
X = NullableArray(rand(N), rand(Bool, N))
ni = NullityIndex(X)
print("NullityIndex(X) (~half missing entries, N = $N)")
@time NullityIndex(X)
a = f((X, ni))
b = g(X)
println("f(X) = ", a, " g(X) = ", b)
println()
print("f (uses NullityIndex): "); @time f((X, ni))
print("g (normal looping): "); @time g(X)
nothing
end
@davidagold
Copy link
Author

Yes, this is better:

julia> profile(10_000_000)
NullityIndex(X) (~half missing entries, N = 10000000) 106.550 milliseconds (3 allocations: 78125 KB, 10.81% gc time)
f(X) = Nullable(2.4977616855296516e6) g(X) = Nullable(2.4977616855296516e6)

f (uses NullityIndex):   11.968 milliseconds (1 allocation: 32 bytes)
g (normal looping):      53.224 milliseconds

@johnmyleswhite
Copy link

💯

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