Skip to content

Commit

Permalink
Add benchmarks for Nullable (#24)
Browse files Browse the repository at this point in the history
Includes in particular a reduced version of NullableArrays to measure loop
performance.
  • Loading branch information
nalimilan authored and jrevels committed Sep 18, 2016
1 parent 4e3c03e commit 83888b9
Show file tree
Hide file tree
Showing 2 changed files with 139 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/BaseBenchmarks.jl
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ const MODULES = Dict("array" => :ArrayBenchmarks,
"io" => :IOBenchmarks,
"linalg" => :LinAlgBenchmarks,
"micro" => :MicroBenchmarks,
"nullable" => :NullableBenchmarks,
"parallel" => :ParallelBenchmarks,
"problem" => :ProblemBenchmarks,
"scalar" => :ScalarBenchmarks,
Expand Down
138 changes: 138 additions & 0 deletions src/nullable/NullableBenchmarks.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
module NullableBenchmarks

include(joinpath(dirname(@__FILE__), "..", "utils", "RandUtils.jl"))

using .RandUtils
using BenchmarkTools

const SUITE = BenchmarkGroup()

####################
# basic operations #
####################

g = addgroup!(SUITE, "basic")

for T in (Bool, Int8, Int64, Float32, Float64, BigInt, BigFloat)
x = Nullable(one(T))
g["get1", string(x)] = @benchmarkable get($x)

for x in (Nullable(one(T)), Nullable{T}())
g["isnull", string(x)] = @benchmarkable isnull($x)
g["get2", string(x)] = @benchmarkable get($x, $(zero(T)))

for y in (Nullable(one(T)), Nullable(zero(T)), Nullable{T}())
g["isequal", string(x), string(y)] = @benchmarkable isequal($x, $y)
end
end
end

####################
# nullable array #
####################

g = addgroup!(SUITE, "nullablearray")

immutable NullableArray{T, N} <: AbstractArray{Nullable{T}, N}
values::Array{T, N}
isnull::Array{Bool, N}
end

@inline function Base.getindex{T, N}(X::NullableArray{T, N}, I::Int...)
if isbits(T)
Nullable{T}(X.values[I...], X.isnull[I...])
else
if X.isnull[I...]
Nullable{T}()
else
Nullable{T}(X.values[I...])
end
end
end

Base.size(X::NullableArray) = size(X.values)
Base.linearindexing{T<:NullableArray}(::Type{T}) = Base.LinearFast()

const VEC_LENGTH = 1000

function perf_sum{T<:Nullable}(X::AbstractArray{T})
S = eltype(T)
s = zero(S)+zero(S)
@inbounds @simd for i in eachindex(X)
s += get(X[i], zero(S))
end
s
end

function perf_countnulls{T<:Nullable}(X::AbstractArray{T})
n = 0
@inbounds for i in eachindex(X)
n += isnull(X[i])
end
n
end

function perf_countequals{T<:Nullable}(X::AbstractArray{T}, Y::AbstractArray{T})
n = 0
@inbounds for i in eachindex(X, Y)
n += isequal(X[i], Y[i])
end
n
end

for T in (Bool, Int8, Int64, Float32, Float64, BigInt, BigFloat, Complex{Float64})
if T == BigInt
S = Int128
elseif T == BigFloat
S = Float64
else
S = T
end

# 10% of missing values
X = NullableArray(Array{T}(samerand(S, VEC_LENGTH)), Array(samerand(VEC_LENGTH) .> .9))
Y = NullableArray(Array{T}(samerand(S, VEC_LENGTH)), Array(samerand(VEC_LENGTH) .> .9))

for (A, X, Y) in (("NullableArray", X, Y), ("Array", collect(X), collect(Y)))
g["perf_sum", A, string(T)] = @benchmarkable perf_sum($X)
g["perf_countnulls", A, string(T)] = @benchmarkable perf_countnulls($X)
g["perf_countequals", A, string(T)] = @benchmarkable perf_countequals($X, $Y)
end
end

function perf_all(X::AbstractArray{Nullable{Bool}})
@inbounds for i in eachindex(X)
x = X[i]
if isnull(x)
return Nullable{Bool}()
elseif !get(x)
return Nullable(false)
end
end
Nullable(true)
end

function perf_any(X::AbstractArray{Nullable{Bool}})
allnull = true
@inbounds for i in eachindex(X)
x = X[i]
if !isnull(x)
allnull = false
get(x) && return Nullable(true)
end
end
allnull ? Nullable{Bool}() : Nullable(false)
end

# Ensure no short-circuit happens
X = NullableArray(fill(true, VEC_LENGTH), fill(false, VEC_LENGTH))
# 10% of missing values
Y = NullableArray(fill(false, VEC_LENGTH), Array(samerand(VEC_LENGTH) .> .9))

g["perf_all", "NullableArray"] = @benchmarkable perf_all($X)
g["perf_any", "NullableArray"] = @benchmarkable perf_any($Y)

g["perf_all", "Array"] = @benchmarkable perf_all($(collect(X)))
g["perf_any", "Array"] = @benchmarkable perf_any($(collect(Y)))

end # module

0 comments on commit 83888b9

Please sign in to comment.