Created
September 26, 2020 22:23
-
-
Save tisztamo/b1db3f385ac75288412ef41fa7157cac to your computer and use it in GitHub Desktop.
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
# The JIT compiler | |
function compile(op, fixtype2) | |
name = nameof(op) | |
compiled_name = Symbol("_comp_$(nameof(op))") | |
expr = quote | |
@inline function $compiled_name(arg1::A) | |
if arg1 isa $fixtype2 | |
return $name(arg1) | |
end | |
return $name(arg1) # Same on both routes: JIT compilation is a no-op on the optimized code | |
end | |
end | |
return eval(expr) | |
end | |
# Demo | |
const NUM_TYPES = 2*10 | |
const QUEUE_LENGTH = 100 | |
abstract type A{T} end | |
struct C1{T} <: A{T} end | |
struct C2{T} <: A{T} end | |
const c1_count = Ref(0) | |
const c2_count = Ref(0) | |
reset() = (c1_count[] = 0; c2_count[] = 0) | |
count_subtypes(a::A) = nothing | |
count_subtypes(c1::C1) = (c1_count[] = c1_count[] + 1; nothing) | |
count_subtypes(c2::C2) = (c2_count[] = c2_count[] + 1; nothing) | |
function createq(alpha = 0.7, ql = QUEUE_LENGTH, nt = NUM_TYPES) | |
@assert ql >= nt | |
return [rand() < alpha ? C1{Val(i % nt)}() : C2{Val(i % nt)}() for i = 1:ql] | |
end | |
using BenchmarkTools | |
for alpha = 0.1:0.1:0.2 | |
print("\n$alpha: c1_count / c2_count goal: $(round((alpha / (1 - alpha)); digits=2)) Dynamic dispatch:") | |
@btime foreach(count_subtypes, q) setup=(reset(); q=createq($alpha)) | |
# Based on empirical data, a sophisticated optimization decides what should run fast | |
# i.e which type to handle in a separate, possibly inlined route | |
fasttype = c1_count[] > c2_count[] ? C1 : C2 | |
print(" Measured ratio: $(round(c1_count[] / c2_count[]; digits=2)) => JIT on $fasttype:") | |
compile(count_subtypes, fasttype) | |
# Voila, 2.5-30x speedup | |
@btime foreach(_comp_count_subtypes, q) setup=(reset(); q=createq($alpha)) | |
end | |
println("Compilation time:") | |
@time compile(count_subtypes, C2) | |
@time compile(count_subtypes, C1) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment