Last active
August 29, 2015 14:13
-
-
Save carlobaldassi/683bcf2ec8b9a10687e2 to your computer and use it in GitHub Desktop.
NullableVector performance with random access
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module NV | |
immutable NullableVector{T} | |
isnull::BitVector | |
values::Vector{T} | |
end | |
@inline Base.length(nv::NullableVector) = length(nv.isnull) | |
@inline function Base.getindex(nv::NullableVector{Float64}, i::Integer) | |
if nv.isnull[i] | |
return Nullable{Float64}() | |
else | |
@inbounds x = Nullable{Float64}(nv.values[i]) | |
return x | |
end | |
end | |
@inline function Base.unsafe_getindex(nv::NullableVector{Float64}, i::Integer) | |
if Base.unsafe_getindex(nv.isnull, i) | |
return Nullable{Float64}() | |
else | |
@inbounds x = nv.values[i] | |
return Nullable{Float64}(x) | |
end | |
end | |
function f1(nv::NullableVector{Float64}, I::Vector{Int}) | |
s, n = 0.0, 0 | |
for i in I | |
nv_i = nv[i] | |
#nv_i = Base.unsafe_getindex(nv, i) | |
if !isnull(nv_i) | |
s += get(nv_i) | |
n += 1 | |
end | |
end | |
return s / n | |
end | |
function f2(nv::NullableVector{Float64}, I) | |
s, n = 0.0, 0 | |
for i in I | |
if !isnull(nv[i]) | |
#if !isnull(Base.unsafe_getindex(nv, i)) | |
#s += get(Base.unsafe_getindex(nv, i)) | |
s += get(nv[i]) | |
n += 1 | |
end | |
end | |
return s / n | |
end | |
function g1(v::Vector{Float64}, I) | |
s, n = 0.0, 0 | |
for i in I | |
v_i = v[i] | |
if !isnan(v_i) | |
s += v_i | |
n += 1 | |
end | |
end | |
return s / n | |
end | |
function g2(v::Vector{Float64}, I) | |
s, n = 0.0, 0 | |
for i in I | |
if !isnan(v[i]) | |
s += v[i] | |
n += 1 | |
end | |
end | |
return s / n | |
end | |
function h1(v::Vector{Nullable{Float64}}, I) | |
s, n = 0.0, 0 | |
for i in I | |
v_i = v[i] | |
if !isnull(v_i) | |
s += get(v_i) | |
n += 1 | |
end | |
end | |
return s / n | |
end | |
function h2(v::Vector{Nullable{Float64}}, I) | |
s, n = 0.0, 0 | |
for i in I | |
if !isnull(v[i]) | |
s += get(v[i]) | |
n += 1 | |
end | |
end | |
return s / n | |
end | |
function bench(p = 0.01) | |
N = 50_000_000 | |
v = randn(N) | |
m = bitpack(Bool[rand() < p for i = 1:N]) | |
nv = NullableVector(m, copy(v)) | |
vn = Nullable{Float64}[m[i] ? Nullable{Float64}(v[i]) : Nullable{Float64}() for i = 1:length(v)] | |
ii = randperm(N) | |
@printf("NullableVector{Float64} w/ One GetIndex Call\n") | |
f1(nv, ii) | |
@time f1(nv, ii) | |
@time f1(nv, ii) | |
@time f1(nv, ii) | |
@printf("NullableVector{Float64} w/ Two GetIndex Calls\n") | |
f2(nv, ii) | |
@time f2(nv, ii) | |
@time f2(nv, ii) | |
@time f2(nv, ii) | |
@printf("Vector{Float64} w/ One GetIndex Call\n") | |
g1(v, ii) | |
@time g1(v, ii) | |
@time g1(v, ii) | |
@time g1(v, ii) | |
@printf("Vector{Float64} w/ Two GetIndex Calls\n") | |
g2(v, ii) | |
@time g2(v, ii) | |
@time g2(v, ii) | |
@time g2(v, ii) | |
@printf("Vector{Nullable{Float64}} w/ One GetIndex Call\n") | |
h1(vn, ii) | |
@time h1(vn, ii) | |
@time h1(vn, ii) | |
@time h1(vn, ii) | |
@printf("Vector{Nullable{Float64}} w/ Two GetIndex Calls\n") | |
h2(vn, ii) | |
@time h2(vn, ii) | |
@time h2(vn, ii) | |
@time h2(vn, ii) | |
nothing | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
results for various null density levels: