Created
June 9, 2018 13:08
-
-
Save jwscook/e8440d7f76c92b4fb622b58b899f12c2 to your computer and use it in GitHub Desktop.
Avoiding functions in types; performance comparison & invitation for code review
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 Functionals | |
abstract type Abstract end | |
type Functional <: Abstract | |
lower::Float64 | |
upper::Float64 | |
end | |
Functional(t::Float64) = Functional(0.0, 12.0 * t) | |
end |
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
include("Functionals.jl") | |
include("Objects.jl") | |
include("Work.jl") | |
using BenchmarkTools | |
const t = Float64(π) | |
O = Objects.Object(t) | |
F = Functionals.Functional(t) | |
function (Functionals.Functional)(x::T, ::Type{Val{false}}) where {T} | |
return exp(-x.^2 / t^2) | |
end | |
function (Functionals.Functional)(x::T, ::Type{Val{true}}) where {T} | |
return -2 * x / t^2 * exp(-x.^2 / t^2) | |
end | |
#make sure they all do the same number crunching | |
@show Work.work(t, false), Work.work(O, false), Work.work(F, false) | |
@show Work.work(t, true), Work.work(O, true), Work.work(F, true) | |
# assert that they do... | |
@assert Work.work(O, false) == Work.work(F, false) | |
@assert Work.work(O, true) == Work.work(F, true) | |
@assert Work.work(O, true) == Work.work(t, true) | |
@assert Work.work(O, false) == Work.work(t, false) | |
# run a few times out of order in case of background cpu usage | |
@btime Work.work($t, false) | |
@btime Work.work($O, false) | |
@btime Work.work($F, false) | |
@btime Work.work($t, true) | |
@btime Work.work($O, true) | |
@btime Work.work($F, true) | |
@btime Work.work($t, false) | |
@btime Work.work($t, true) | |
@btime Work.work($O, false) | |
@btime Work.work($O, true) | |
@btime Work.work($F, false) | |
@btime Work.work($F, true) | |
# print warntype | |
@show "#########" | |
@show "code_warntype, Work.work(t, false)" | |
@code_warntype Work.work(t, false) | |
@show "#########" | |
@show "code_warntype, Work.work(O, false)" | |
@code_warntype Work.work(O, false) | |
@show "#########" | |
@show "code_warntype, Work.work(F, false)" | |
@code_warntype Work.work(F, false) | |
@show "#########" | |
# look at native code | |
@show "#########" | |
@show "code_native, Work.work(t, false)" | |
@code_native Work.work(t, false) | |
@show "#########" | |
@show "code_native, Work.work(O, false)" | |
@code_native Work.work(O, false) | |
@show "#########" | |
@show "code_native, Work.work(F, false)" | |
@code_native Work.work(F, false) |
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 Objects | |
abstract type Abstract end | |
type Object{T<:Function, U<:Function} <: Abstract | |
F::T | |
dFdv::U | |
lower::Float64 | |
upper::Float64 | |
end | |
defaultF(t::T) where{T} = x::T -> exp(-x^2 / t^2) | |
defaultdFdv(t::T) where{T} = x::T -> - 2 * x / t^2 * exp(-x^2 / t^2) | |
Object(t::T) where {T} = Object(defaultF(t), defaultdFdv(t), 0.0, 12.0 * t) | |
end # module |
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 Work | |
using QuadGK, SpecialFunctions | |
import Objects, Functionals | |
kernel(x::T) where {T<:Number} = (x^3)::T *besselj(3, x)::T * besselj(-2, x)::T | |
function work(obj::T, ∂::Bool) where {T<:Objects.Abstract} | |
integrand(x::U) where {U<:Number} = ∂ ? kernel(x)*obj.dFdv(x) : kernel(x)*obj.F(x) | |
return QuadGK.quadgk(integrand, obj.lower, obj.upper)[1] | |
end | |
function work(fun::T, ∂::Bool) where {T<:Functionals.Abstract} | |
integrand(x::U) where {U<:Number} = kernel(x) * T(x, Val{∂}) | |
return QuadGK.quadgk(integrand, fun.lower, fun.upper)[1] | |
end | |
function work(t::Float64, ∂::Bool) | |
integrand(x::T) where {T<:Number} = ∂ ? | |
kernel(x)*(- 2 * x / t^2 * exp(-x^2 / t^2)) : kernel(x)*exp(-x^2/t^2) | |
return QuadGK.quadgk(integrand, 0.0, 12.0 * t)[1] | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment