Skip to content

Instantly share code, notes, and snippets.

@singularitti
Forked from felipenoris/enum-vs-dispatch.jl
Last active April 20, 2020 02:34
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 singularitti/9b10bd4f3d025571807953c3c9631e93 to your computer and use it in GitHub Desktop.
Save singularitti/9b10bd4f3d025571807953c3c9631e93 to your computer and use it in GitHub Desktop.
Benchmark of dispatch on enum types and types #Julia #benchmark
using Test
using BenchmarkTools
@enum ECompoundingType EContinuous = 1 ESimple = 2 EExponential = 3
abstract type TCompoundType end
struct TContinuous <: TCompoundType end
struct TSimple <: TCompoundType end
struct TExponential <: TCompoundType end
function ediscount_factor(compounding::ECompoundingType, r::Real, t::Real)
if compounding == EContinuous
return 1.0 / exp(r * t)
elseif compounding == ESimple
return 1.0 / (1 + r * t)
elseif compounding == EExponential
return 1.0 / ((1 + r)^t)
else
error("Unknown compounding type $(compounding)")
end
end
vdiscount_factor(::Type{Val{EContinuous}}, r::Real, t::Real) = 1.0 / exp(r * t)
vdiscount_factor(::Type{Val{ESimple}}, r::Real, t::Real) = 1.0 / (1 + r * t)
vdiscount_factor(::Type{Val{EExponential}}, r::Real, t::Real) = 1.0 / ((1 + r)^t)
tdiscount_factor(::TContinuous, r::Real, t::Real) = 1.0 / exp(r * t)
tdiscount_factor(::TSimple, r::Real, t::Real) = 1.0 / (1 + r * t)
tdiscount_factor(::TExponential, r::Real, t::Real) = 1.0 / ((1 + r)^t)
tdiscount_factor(c::TCompoundType, r::Real, t::Real) = error("not implemented for type $(typeof(c))")
(::TContinuous)(r::Real, t::Real) = 1.0 / exp(r * t)
(::TSimple)(r::Real, t::Real) = 1.0 / (1 + r * t)
(::TExponential)(r::Real, t::Real) = 1.0 / ((1 + r)^t)
compound_1(r::Real, t::Real) = 1.0 / exp(r * t)
compound_2(r::Real, t::Real) = 1.0 / (1 + r * t)
compound_3(r::Real, t::Real) = 1.0 / ((1 + r)^t)
const _compound_functions = [compound_1, compound_2, compound_3]
rdiscount_factor(compounding::ECompoundingType, r::Real, t::Real) = _compound_functions[Int(compounding)](r, t)
func_c = TContinuous()
func_s = TSimple()
func_e = TExponential()
# Continuous
ef_c = ediscount_factor(EContinuous, 0.15, 2.0)
vf_c = vdiscount_factor(Val{EContinuous}, 0.15, 2.0)
tf_c = tdiscount_factor(TContinuous(), 0.15, 2.0)
rf_c = rdiscount_factor(EContinuous, 0.15, 2.0)
ff_c = func_c(0.15, 2.0)
# Simple
ef_s = ediscount_factor(ESimple, 0.15, 2.0)
vf_s = vdiscount_factor(Val{ESimple}, 0.15, 2.0)
tf_s = tdiscount_factor(TSimple(), 0.15, 2.0)
rf_s = rdiscount_factor(ESimple, 0.15, 2.0)
ff_s = func_s(0.15, 2.0)
# Exponential
ef_e = ediscount_factor(EExponential, 0.15, 2.0)
vf_e = vdiscount_factor(Val{EExponential}, 0.15, 2.0)
tf_e = tdiscount_factor(TExponential(), 0.15, 2.0)
rf_e = rdiscount_factor(EExponential, 0.15, 2.0)
ff_e = func_e(0.15, 2.0)
@test ef_c == vf_c == tf_c == rf_c == ff_c
@test ef_s == vf_s == tf_s == rf_s == ff_s
@test ef_e == vf_e == tf_e == rf_e == ff_e
#EContinuous=1 ESimple=2 EExponential=3
println("enums with switch code")
@btime ediscount_factor(EContinuous, 0.15, 2.0)
@btime ediscount_factor(ESimple, 0.15, 2.0)
@btime ediscount_factor(EExponential, 0.15, 2.0)
println("Dispatch via Val Type")
@btime vdiscount_factor(Val{EContinuous}, 0.15, 2.0)
@btime vdiscount_factor(Val{ESimple}, 0.15, 2.0)
@btime vdiscount_factor(Val{EExponential}, 0.15, 2.0)
println("Dispatch via Const Val Type")
const cValCont = Val{EContinuous}
const cValSim = Val{ESimple}
const cValExp = Val{EExponential}
@btime vdiscount_factor(cValCont, 0.15, 2.0)
@btime vdiscount_factor(cValSim, 0.15, 2.0)
@btime vdiscount_factor(cValExp, 0.15, 2.0)
println("Dispatch via Type")
@btime tdiscount_factor(TContinuous(), 0.15, 2.0)
@btime tdiscount_factor(TSimple(), 0.15, 2.0)
@btime tdiscount_factor(TExponential(), 0.15, 2.0)
println("Vector of functions dispatch")
@btime rdiscount_factor(EContinuous, 0.15, 2.0)
@btime rdiscount_factor(ESimple, 0.15, 2.0)
@btime rdiscount_factor(EExponential, 0.15, 2.0)
println("Functors")
fc = TContinuous()
fs = TSimple()
fe = TExponential()
@btime fc(0.15, 2.0)
@btime fs(0.15, 2.0)
@btime fe(0.15, 2.0)
println("Const Functors")
const cfc = TContinuous()
const cfs = TSimple()
const cfe = TExponential()
@btime cfc(0.15, 2.0)
@btime cfs(0.15, 2.0)
@btime cfe(0.15, 2.0)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment