Skip to content

Instantly share code, notes, and snippets.

@felipenoris
Last active January 12, 2024 01:49
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save felipenoris/660537161af33db34dcb to your computer and use it in GitHub Desktop.
Save felipenoris/660537161af33db34dcb to your computer and use it in GitHub Desktop.
using Base.Test
@enum ECompoundingType EContinuous=1 ESimple=2 EExponential=3
abstract TCompoundType
type TContinuous <: TCompoundType end
type TSimple <: TCompoundType end
type 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
function vdiscount_factor(::Type{Val{EContinuous}}, r::Real, t::Real)
return 1.0 / exp(r*t)
end
function vdiscount_factor(::Type{Val{ESimple}}, r::Real, t::Real)
return 1.0 / (1 + r*t)
end
function vdiscount_factor(::Type{Val{EExponential}}, r::Real, t::Real)
return 1.0 / ((1+r)^t)
end
function tdiscount_factor(::TContinuous, r::Real, t::Real)
return 1.0 / exp(r*t)
end
function tdiscount_factor(::TSimple, r::Real, t::Real)
return 1.0 / (1 + r*t)
end
function tdiscount_factor(::TExponential, r::Real, t::Real)
return 1.0 / ((1+r)^t)
end
function tdiscount_factor(c::TCompoundType, r::Real, t::Real)
error("not implemented for type $(typeof(c))")
end
Base.call(c::TContinuous, r::Real, t::Real) = 1.0 / exp(r*t)
Base.call(c::TSimple, r::Real, t::Real) = 1.0 / (1 + r*t)
Base.call(c::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]
function rdiscount_factor(compounding::ECompoundingType, r::Real, t::Real)
return _compound_functions[Int(compounding)](r,t)
end
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")
@time begin
for i = 1:10000000
ediscount_factor(EContinuous, 0.15, 2.0)
ediscount_factor(ESimple, 0.15, 2.0)
ediscount_factor(EExponential, 0.15, 2.0)
end
end
println("Dispatch via Val Type")
@time begin
for i = 1:10000000
vdiscount_factor(Val{EContinuous}, 0.15, 2.0)
vdiscount_factor(Val{ESimple}, 0.15, 2.0)
vdiscount_factor(Val{EExponential}, 0.15, 2.0)
end
end
println("Dispatch via Const Val Type")
const cValCont = Val{EContinuous}
const cValSim = Val{ESimple}
const cValExp = Val{EExponential}
@time begin
for i = 1:10000000
vdiscount_factor(cValCont, 0.15, 2.0)
vdiscount_factor(cValSim, 0.15, 2.0)
vdiscount_factor(cValExp, 0.15, 2.0)
end
end
println("Dispatch via Type")
@time begin
for i = 1:10000000
tdiscount_factor(TContinuous(), 0.15, 2.0)
tdiscount_factor(TSimple(), 0.15, 2.0)
tdiscount_factor(TExponential(), 0.15, 2.0)
end
end
println("Vector of functions dispatch")
@time begin
for i = 1:10000000
rdiscount_factor(EContinuous, 0.15, 2.0)
rdiscount_factor(ESimple, 0.15, 2.0)
rdiscount_factor(EExponential, 0.15, 2.0)
end
end
println("Functors")
fc = TContinuous()
fs = TSimple()
fe = TExponential()
@time begin
for i = 1:10000000
fc(0.15, 2.0)
fs(0.15, 2.0)
fe(0.15, 2.0)
end
end
println("Const Functors")
const cfc = TContinuous()
const cfs = TSimple()
const cfe = TExponential()
@time begin
for i = 1:10000000
cfc(0.15, 2.0)
cfs(0.15, 2.0)
cfe(0.15, 2.0)
end
end
julia> include("enum-vs-dispatch.jl")
enums with switch code
323.515 milliseconds
Dispatch via Val Type
1.068 seconds (30000 k allocations: 458 MB, 1.96% gc time)
Dispatch via Const Val Type
145.355 milliseconds
Dispatch via Type
148.047 milliseconds
Vector of functions dispatch
833.969 milliseconds (30000 k allocations: 458 MB, 2.14% gc time)
Functors
1.011 seconds (30000 k allocations: 458 MB, 1.62% gc time)
Const Functors
147.741 milliseconds
@singularitti
Copy link

I update it so it can be used for Julia 1.0 and above: https://gist.github.com/singularitti/9b10bd4f3d025571807953c3c9631e93

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