Skip to content

Commit

Permalink
reorder ml-matches to avoid catastrophic performance case
Browse files Browse the repository at this point in the history
This ordering of the algorithm abandons the elegant insertion in favor
of using another copy of Tarjan's SCC code. This enables us to abort the
algorithm in O(k*n) time, instead of always running full O(n*n) time,
where k is `min(lim,n)`.

For example, to sort 1338 methods:

Before:
julia> @time Base._methods_by_ftype(Tuple{typeof(Core.kwcall), NamedTuple, Any, Vararg{Any}}, 3, Base.get_world_counter());
  0.136609 seconds (22.74 k allocations: 1.104 MiB)
julia> @time Base._methods_by_ftype(Tuple{typeof(Core.kwcall), NamedTuple, Any, Vararg{Any}}, -1, Base.get_world_counter());
  0.046280 seconds (9.95 k allocations: 497.453 KiB)
julia> @time Base._methods_by_ftype(Tuple{typeof(Core.kwcall), NamedTuple, Any, Vararg{Any}}, 30000, Base.get_world_counter());
  0.132588 seconds (22.73 k allocations: 1.103 MiB)
julia> @time Base._methods_by_ftype(Tuple{typeof(Core.kwcall), NamedTuple, Any, Vararg{Any}}, 30000, Base.get_world_counter());
  0.135912 seconds (22.73 k allocations: 1.103 MiB)

After:
julia> @time Base._methods_by_ftype(Tuple{typeof(Core.kwcall), NamedTuple, Any, Vararg{Any}}, 3, Base.get_world_counter());
  0.001040 seconds (1.47 k allocations: 88.375 KiB)
julia> @time Base._methods_by_ftype(Tuple{typeof(Core.kwcall), NamedTuple, Any, Vararg{Any}}, -1, Base.get_world_counter());
  0.039167 seconds (8.24 k allocations: 423.984 KiB)
julia> @time Base._methods_by_ftype(Tuple{typeof(Core.kwcall), NamedTuple, Any, Vararg{Any}}, 30000, Base.get_world_counter());
  0.081354 seconds (8.26 k allocations: 424.734 KiB)
julia> @time Base._methods_by_ftype(Tuple{typeof(Core.kwcall), NamedTuple, Any, Vararg{Any}}, 30000, Base.get_world_counter());
  0.080849 seconds (8.26 k allocations: 424.734 KiB)

And makes inference faster in rare cases (this particular example came
up because the expression below occurs appears in `@test`
macroexpansion), both before loading loading more packages, such as
OmniPackage, and afterwards, where the cost is almost unchanged
afterwards, versus increasing about 50x.

julia> f() = x(args...; kwargs...); @time @code_typed optimize=false f();
  0.143523 seconds (23.25 k allocations: 1.128 MiB, 99.96% compilation time) # before
  0.001172 seconds (1.86 k allocations: 108.656 KiB, 97.71% compilation time) # after
  • Loading branch information
vtjnash committed May 12, 2023
1 parent c6fc12c commit 8bbbf3e
Show file tree
Hide file tree
Showing 4 changed files with 268 additions and 318 deletions.
Loading

0 comments on commit 8bbbf3e

Please sign in to comment.