Skip to content

Commit

Permalink
Add benchmarks for Nullable
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 committed Sep 16, 2016
1 parent 4e3c03e commit 1c5d318
Show file tree
Hide file tree
Showing 2 changed files with 132 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
131 changes: 131 additions & 0 deletions src/nullable/NullableBenchmarks.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
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)

const VEC_LENGTH = 1000

function perf_sum{T}(X::NullableArray{T})
s = zero(typeof(zero(T)+zero(T)))
@inbounds for i in eachindex(X)
s += get(X[i], zero(T))
end
s
end

function perf_countnulls(X::NullableArray)
n = 0
@inbounds for i in eachindex(X)
n += isnull(X[i])
end
n
end

function perf_countequals(X::NullableArray, Y::NullableArray)
s = 0
@inbounds for i in eachindex(X, Y)
s += isequal(X[i], Y[i])
end
s
end

for T in (Bool, Int8, Int64, Float32, Float64, BigInt, BigFloat)
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))

g["perf_sum", string(T)] = @benchmarkable perf_sum($X)
g["perf_countnulls", string(T)] = @benchmarkable perf_countnulls($X)
g["perf_countequals", string(T)] = @benchmarkable perf_countequals($X, $Y)
end


function perf_all(X::NullableArray{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::NullableArray{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"] = @benchmarkable perf_all($X)
g["perf_any"] = @benchmarkable perf_any($Y)

end # module

0 comments on commit 1c5d318

Please sign in to comment.