# When does it make sense to use \`Base.MultiplicativeInverses\`

**URL:** <https://discourse.julialang.org/t/when-does-it-make-sense-to-use-base-multiplicativeinverses/131711>\
**Category:** Performance\
**Tags:** base, multiplicativeinvers\
**Created:** [August 19, 2025, 2:28pm UTC](https://discourse.julialang.org/t/when-does-it-make-sense-to-use-base-multiplicativeinverses/131711 "2025-08-19T14:28:09Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![kunzaatko](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kunzaatko/32/25153_2.png) [@kunzaatko](https://discourse.julialang.org/u/kunzaatko)\
**Post date:** [August 19, 2025, 2:28pm UTC](https://discourse.julialang.org/t/when-does-it-make-sense-to-use-base-multiplicativeinverses/131711/1 "2025-08-19T14:28:09Z")

</div>

When does it make sense to use the `Base.MultiplicativeInverses`? I am considering storing the `MultiplicativeInverse` in my `AbstractArray` subtype which uses some index calculations based on some fields and the `parent` array. I thought that storing the `MultiplicativeInverse` of the numbers that I often divide by in my subtype would lead to a significant performance boost, but when I ran a quick benchmark I do not see any difference. Hence the question… When is it useful? What are some rules of thumb that I can abide by?

```julia-repl
julia> un = rand(UInt64, 10_000);

julia> @btime div.($un, 56);
  6.620 μs (3 allocations: 78.20 KiB)

julia> using Base.MultiplicativeInverses

julia> @btime div.($un, $(MultiplicativeInverses.multiplicativeinverse(MultiplicativeInverses.unsigned(56))));
  6.530 μs (3 allocations: 78.20 KiB)

```

---

<div class="post-metadata">

**Author:** ![mbauman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mbauman/32/31082_2.png) [@mbauman](https://discourse.julialang.org/u/mbauman)\
**Post date:** [August 19, 2025, 3:02pm UTC](https://discourse.julialang.org/t/when-does-it-make-sense-to-use-base-multiplicativeinverses/131711/2 "2025-08-19T15:02:00Z")

</div>

Right now you’re benchmarking with the constant `56`. If it’s truly a constant, then that’ll probably always be equal or fastest (because LLVM does a similar transform on my platform!). Look ma, no `div`s:

```julia-auto
julia> f(x) = div(x, 56)
f (generic function with 1 method)

julia> @code_native debuginfo=:none f(123123)
	.section	__TEXT,__ text,regular,pure_instructions
	.build_version macos, 15, 0
	.globl	_julia_f_10054 ; -- Begin function julia_f_10054
	.p2align	2
_julia_f_10054: ; @julia_f_10054
; Function Signature: f(Int64)
; %bb.0: ; %pass
	;DEBUG_VALUE: f:x <- $x0
	;DEBUG_VALUE: f:x <- $x0
	mov	x8, #18725
	movk	x8, #9362, lsl #16
	movk	x8, #37449, lsl #32
	movk	x8, #18724, lsl #48
	smulh	x8, x0, x8
	asr	x9, x8, #4
	add	x0, x9, x8, lsr #63
	ret
                                        ; -- End function
.subsections_via_symbols

```

You’d want to benchmark it without the constant propagation:

```julia-auto
julia> @btime div.($un, 56); # constant!
  2.718 μs (3 allocations: 96.06 KiB)

julia> @btime div.($un, $(Ref(56))[]);
  6.267 μs (3 allocations: 96.06 KiB)

julia> @btime div.($un, $(Ref(MultiplicativeInverses.multiplicativeinverse(MultiplicativeInverses.unsigned(56))))[]);
  3.068 μs (3 allocations: 96.06 KiB)

```

---

<div class="post-metadata">

**Author:** ![kunzaatko](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kunzaatko/32/25153_2.png) [@kunzaatko](https://discourse.julialang.org/u/kunzaatko)\
**Post date:** [August 19, 2025, 3:05pm UTC](https://discourse.julialang.org/t/when-does-it-make-sense-to-use-base-multiplicativeinverses/131711/3 "2025-08-19T15:05:45Z")

</div>

So if I just store the size that I `div` with within the struct I would get the same result because llvm would propagate the constant is this correct?

---

<div class="post-metadata">

**Author:** ![mbauman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mbauman/32/31082_2.png) [@mbauman](https://discourse.julialang.org/u/mbauman)\
**Post date:** [August 19, 2025, 3:07pm UTC](https://discourse.julialang.org/t/when-does-it-make-sense-to-use-base-multiplicativeinverses/131711/4 "2025-08-19T15:07:28Z")

</div>

It’d have to be a compile-time constant _for Julia_. If you’re storing it as a field in a struct, it’s definitely not a constant. If you store it as a type parameter, then it’d be a compile-time constant for type-stable code.

---

<div class="post-metadata">

**Author:** ![jakobnissen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jakobnissen/32/13477_2.png) [@jakobnissen](https://discourse.julialang.org/u/jakobnissen)\
**Post date:** [August 19, 2025, 3:26pm UTC](https://discourse.julialang.org/t/when-does-it-make-sense-to-use-base-multiplicativeinverses/131711/5 "2025-08-19T15:26:20Z")

</div>

Is `MultiplicativeInverses` public? As far as I can see, it’s neither documented, nor exported nor marked public. So I don’t think it’s fit for consumption.

---

<div class="post-metadata">

**Author:** ![jling](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jling/32/212909_2.png) [@jling](https://discourse.julialang.org/u/jling)\
**Post date:** [August 19, 2025, 3:26pm UTC](https://discourse.julialang.org/t/when-does-it-make-sense-to-use-base-multiplicativeinverses/131711/6 "2025-08-19T15:26:55Z")

</div>

> **[Julia Documentation · The Julia Language](https://docs.julialang.org/en/v1.13-dev/?q=multiplicativeinverse)**
>
> Documentation for The Julia Language.

can’t even find it

---

<div class="post-metadata">

**Author:** ![kunzaatko](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kunzaatko/32/25153_2.png) [@kunzaatko](https://discourse.julialang.org/u/kunzaatko)\
**Post date:** [August 19, 2025, 4:18pm UTC](https://discourse.julialang.org/t/when-does-it-make-sense-to-use-base-multiplicativeinverses/131711/7 "2025-08-19T16:18:05Z")

</div>

> [@jling](#):
>
> can’t even find it

`FFTViews` considered using it quite a while ago and it didn’t change since. I am not aware if it is used in base. Maybe in `view` / `SubArray` types.
