You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
A colleague shared this profile, showing the Mocking's get_alternate call was taking the majority of the time despite there being no @patch applied:
I often experience that Mocking, once it had been activated indirectly in the shell by running some tests that use mocking, has perf degradation when subsequently running non-mocked code (see profile).
I wonder if we can reduce this overhead?
You can see there are two things taking the time:
the haskey call, from every function that is marked @mockchecking if there is a corresponding @patch
the the macro expand -> current_logger_… call, from the @debug log message (possibly made worse by Improve Mocking debugging #128)
I wonder if we can avoid calling get_alternative at all if we're not iinside Mocking.apply?
e.g. Mocking.apply could set a global / ScopedValue PATCH_ENV_ACTIVE::Bool that can be checked alongside activated() to avoid calling get_alternate at all. (Ofc, would need benchmarking to prove this would reduce the overhead.)
--- a/src/mock.jl+++ b/src/mock.jl@@ -40,7 +40,7 @@ macro mock(expr)
# When `Mocking.activated() == false` then Julia will optimize the
# code below to have zero-overhead by only executing the original expression.
result = quote
- if $activated()+ if $activated() && $PATCH_ENV_ACTIVE[]
args_var = tuple($(args...))
alternate_var = $get_alternate($target, args_var...; call_loc=$call_loc)
if alternate_var !== nothing
--- a/src/patch.jl+++ b/src/patch.jl@@ -206,17 +206,21 @@ end
# https://github.com/JuliaLang/julia/pull/50958
if VERSION >= v"1.11.0-DEV.482"
const PATCH_ENV = ScopedValue(PatchEnv())
- with_active_env(body::Function, pe::PatchEnv) = with(body, PATCH_ENV => pe)+ const PATCH_ENV_ACTIVE = ScopedValue(false)+ with_active_env(body::Function, pe::PatchEnv) = with(body, PATCH_ENV => pe, PATCH_ENV_ACTIVE => true)
Or perhaps even just checking isempty on the patch env would do?
--- a/src/mock.jl+++ b/src/mock.jl@@ -40,7 +40,7 @@ macro mock(expr)
# When `Mocking.activated() == false` then Julia will optimize the
# code below to have zero-overhead by only executing the original expression.
result = quote
- if $activated()+ if $activated() && $(!($isempty($PATCH_ENV[])))
args_var = tuple($(args...))
alternate_var = $get_alternate($target, args_var...; call_loc=$call_loc)
if alternate_var !== nothing
A colleague shared this profile, showing the Mocking's
get_alternatecall was taking the majority of the time despite there being no@patchapplied:I wonder if we can reduce this overhead?
You can see there are two things taking the time:
haskeycall, from every function that is marked@mockchecking if there is a corresponding@patchthe macro expand -> current_logger_…call, from the@debuglog message (possibly made worse by Improve Mocking debugging #128)I wonder if we can avoid calling
get_alternativeat all if we're not iinsideMocking.apply?e.g.
Mocking.applycould set a global / ScopedValuePATCH_ENV_ACTIVE::Boolthat can be checked alongsideactivated()to avoid callingget_alternateat all. (Ofc, would need benchmarking to prove this would reduce the overhead.)Or perhaps even just checking
isemptyon the patch env would do?