diff --git a/Project.toml b/Project.toml index f7f96cc..56d1036 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "MistyClosures" uuid = "dbe65cb8-6be2-42dd-bbc5-4196aaced4f4" authors = ["Will Tebbutt", "Frames White", "Hong Ge"] -version = "1.0.3" +version = "2.0.0" [compat] julia = "1.10" diff --git a/src/MistyClosures.jl b/src/MistyClosures.jl index 162e5eb..a7d338b 100644 --- a/src/MistyClosures.jl +++ b/src/MistyClosures.jl @@ -5,13 +5,18 @@ using Core.Compiler: IRCode import Base: show +# As of 2.0, MistyClosure contains a reference to its IR. This is because `IRCode` is +# a surprisingly bulky type (136B in 1.11.1 -- the same as 17 Float64s). Since especially +# fast access to `ir` is never needed, it is fine to store it out-of-place, thus reducing +# the size of a `MistyClosure` from 176B to 48B. This can have a substantial impact on the +# performance of calling many `OpaqueClosure`s of the same type. struct MistyClosure{Toc<:OpaqueClosure} oc::Toc - ir::IRCode + ir::Base.RefValue{IRCode} end function MistyClosure(ir::IRCode, env...; kwargs...) - return MistyClosure(OpaqueClosure(ir, env...; kwargs...), ir) + return MistyClosure(OpaqueClosure(ir, env...; kwargs...), Ref(ir)) end (mc::MistyClosure)(x::Vararg{Any, N}) where {N} = mc.oc(x...) diff --git a/test/runtests.jl b/test/runtests.jl index 304e0e1..19db474 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -16,7 +16,7 @@ end @test @inferred(mc(5.0)) == sin(5.0) # Default constructor. - mc_default = MistyClosure(OpaqueClosure(ir; do_compile=true), ir) + mc_default = MistyClosure(OpaqueClosure(ir; do_compile=true), Ref(ir)) @test @inferred(mc_default(5.0) == sin(5.0)) # Recommended constructor with env. @@ -25,7 +25,7 @@ end @test @inferred(mc_with_env(4.0)) == Foo(5.0)(4.0) # Default constructor with env. - mc_env_default = MistyClosure(OpaqueClosure(ir_foo, 4.0; do_compile=true), ir_foo) + mc_env_default = MistyClosure(OpaqueClosure(ir_foo, 4.0; do_compile=true), Ref(ir_foo)) @test @inferred(mc_env_default(5.0) == Foo(5.0)(4.0)) # deepcopy