# Speed of \`hasmethod\` with and without kwargs

**URL:** <https://discourse.julialang.org/t/speed-of-hasmethod-with-and-without-kwargs/129847>\
**Category:** Performance\
**Tags:** question\
**Created:** [June 12, 2025, 10:36pm UTC](https://discourse.julialang.org/t/speed-of-hasmethod-with-and-without-kwargs/129847 "2025-06-12T22:36:42Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![mmkrusniak](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mmkrusniak/32/216070_2.png) [@mmkrusniak](https://discourse.julialang.org/u/mmkrusniak)\
**Post date:** [June 12, 2025, 10:36pm UTC](https://discourse.julialang.org/t/speed-of-hasmethod-with-and-without-kwargs/129847/1 "2025-06-12T22:36:42Z")

</div>

I’m a novice at writing high-performance code with Julia (1.11).

I have an unknown function from a user, and I want to check if it accepts any of several possible sets of keyword names. But for reasons unknown to me, `hasmethod` is very slow when applied to kwargs:

```julia
test_no_kw(a) = 1
test_kw(; a) = 2
test_many_kw(; a, b, c) = 3

@btime hasmethod(test_no_kw, (Any,)) # 2 ns
@btime hasmethod(test_kw, (), (:a,)) # 747 ns
@btime hasmethod(test_many_kw, (), (:a, :c, :b)) # 782 ns

```

What exactly is going on under the hood that makes the second call so much slower (and the third call not much slower than that)? Should I avoid checking for keywords like this entirely if I need to write fast code, or is there a workaround?

---

<div class="post-metadata">

**Author:** ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)\
**Post date:** [June 12, 2025, 10:53pm UTC](https://discourse.julialang.org/t/speed-of-hasmethod-with-and-without-kwargs/129847/2 "2025-06-12T22:53:32Z")

</div>

2ns is currently around the benchmark results of integer addition, an indication that the actual call got compiled out of the benchmark loop. Use `$` for runtime arguments in `BenchmarkTools`, it changes quite a bit:

```julia
julia> @btime hasmethod(test_no_kw, (Any,))
  1.000 ns (0 allocations: 0 bytes)
true

julia> @btime hasmethod($test_no_kw, $(Any,))
  625.444 ns (9 allocations: 352 bytes)
true

```

Still slower than involving keyword arguments, I imagine it’s just extra work after method dispatch over the positional arguments.

```julia
julia> @btime hasmethod($test_many_kw, $(), $(:a,))
  1.240 μs (15 allocations: 568 bytes)
true

julia> @btime hasmethod($test_many_kw, $(), $(:a, :c, :b))
  1.260 μs (15 allocations: 600 bytes)
true

```

> [@mmkrusniak](#):
>
> Should I avoid checking for keywords like this entirely if I need to write fast code

Ideally you’re not checking for method existence at runtime.

---

<div class="post-metadata">

**Author:** ![matthias314](https://avatars.discourse-cdn.com/v4/letter/m/a88e4f/32.png) [@matthias314](https://discourse.julialang.org/u/matthias314)\
**Post date:** [June 12, 2025, 11:32pm UTC](https://discourse.julialang.org/t/speed-of-hasmethod-with-and-without-kwargs/129847/3 "2025-06-12T23:32:02Z")

</div>

> [@Benny](#):
>
> the actual call got compiled out of the benchmark loop

I think that’s a realistic scenario if one wants to use `hasmethod` inside a function (with constant keyword names).

Apart from speed, I don’t think that using `hasmethod` is a good idea in this case. The reason is that it cannot deal with functions accepting a variable number of keyword arguments. Imagine the following pattern, which often I find using myself:

```julia
f(x::Int; a = 0) = 1
f(x::Char) = 2
g(x; kw...) = f(x; kw...) + 1

```

Here `hasmethod` is not able to tell for which type of `x` one can use the keyword argument `a`.

If you have enough control over the situation, then you can use traits, for example as follows:

```julia
accepts_kw_a(::typeof(f), ::Type{Int}) = true
accepts_kw_a(::typeof(f), ::Type{Char}) = false
accepts_kw_a(::typeof(g), ::Type{T}) where T = accepts_kw_a(f, T)

```

Maybe you can insists that the person giving you a functions also write a method for the trait.

---

<div class="post-metadata">

**Author:** ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)\
**Post date:** [June 12, 2025, 11:53pm UTC](https://discourse.julialang.org/t/speed-of-hasmethod-with-and-without-kwargs/129847/4 "2025-06-12T23:53:28Z")

</div>

> [@matthias314](#):
>
> I think that’s a realistic scenario if one wants to use `hasmethod` inside a function (with constant keyword names).

You’d need the function and argument types to be constant too, then the compiler is free to do the call at compile-time and be invalidated when method definitions change. Obviously that’s much more limited than a runtime call.
