-
Notifications
You must be signed in to change notification settings - Fork 14
Description
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
haskeycall, from every function that is marked@mockchecking if there is a corresponding@patch - the
the 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_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