# ANN: Anyone need my 2.7x faster factorial (or gamma) function?

**URL:** <https://discourse.julialang.org/t/ann-anyone-need-my-2-7x-faster-factorial-or-gamma-function/19926>\
**Category:** Performance\
**Created:** [January 22, 2019, 12:29pm UTC](https://discourse.julialang.org/t/ann-anyone-need-my-2-7x-faster-factorial-or-gamma-function/19926 "2019-01-22T12:29:33Z")\
**Posts on this page:** 3\
**Page:** 2

<div class="post-metadata">

**Author:** ![improbable22](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/improbable22/32/5464_2.png) [@improbable22](https://discourse.julialang.org/u/improbable22)\
**Post date:** [January 22, 2019, 10:15pm UTC](https://discourse.julialang.org/t/ann-anyone-need-my-2-7x-faster-factorial-or-gamma-function/19926/21 "2019-01-22T22:15:57Z")

</div>

Cool, thanks for explaining. I didn’t realise an un-called `throw` could cost so much – seems like this would affect many things?

Sprinkling `@inline` around & testing is however a task within my pay grade, which I did not perform. Is inlining also the reason that `@btime factorial()` is failing to see differences that `@btime map!(...)` shows?

---

<div class="post-metadata">

**Author:** ![Palli](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/palli/32/3380_2.png) [@Palli](https://discourse.julialang.org/u/Palli)\
**Post date:** [January 23, 2019, 4:20pm UTC](https://discourse.julialang.org/t/ann-anyone-need-my-2-7x-faster-factorial-or-gamma-function/19926/22 "2019-01-23T16:20:32Z")

</div>

> [@improbable22](#):
>
> `gamma(::Int)` only looks up the first 20, but 171 isn’t many to store

You must have been looking at an old commit; the PR already has a look-up table for all 171 integers (ignore most of the “discussion” there, just what I discovered along the way speaking to myself and some “discoveries” tuned out wrong, nobody seems to be reading/reviewing or merging there at the moment):

> <https://github.com/JuliaMath/SpecialFunctions.jl/pull/142/files>
>
> If my https://github.com/JuliaLang/julia/pull/30665 will get pulled this package… WILL break, I think.
> 
> https://github.com/JuliaMath/SpecialFunctions.jl/blob/9d0caf9833d06fad8df114564f143e7f909b984a/src/gamma.jl#L758
> 
> Base.\_fact\_table64 is dangeraous, and as it's a "fact" table, to could alternatively be done here with:
> 
> const \_fact\_table64 = \[cumprod(1:Int64(20))\] # as oppoed to what I changed to: const \_fact\_table64 = \[1; cumprod(1:Int64(20))\]
> 
> Such a change will not automatically benefit from my improved factorial (it seems 22%+ faster), nor would gamma fail if I screwed up...
> 
> This change would need to be merged and tagged, right, before my other PR?
> 
> Isn't this what you call type piracy ("bad")? And while I could easily have missed this, if I had not known about gamma in Julia 0.5, is there a way of knowing (like searching globally in all Julia packages; at least those in METADATA or the new registry)?

> [@improbable22](#):
>
> I didn’t realise an un-called `throw` could cost so much

Right, that was my original goal to get it to be fast; and hopefully with it still at the top of the function. You may want such exceptional cases there for readability (“design-by-contract”). It’s just that in the assembly you don’t want it first, or even in the same function. I was thinking something like Match.jl might eventually handle such and make good code, if Julia compiler itself doesn’t figure out.

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [January 23, 2019, 6:23pm UTC](https://discourse.julialang.org/t/ann-anyone-need-my-2-7x-faster-factorial-or-gamma-function/19926/23 "2019-01-23T18:23:16Z")

</div>

> [@Palli](#):
>
> speaking to myself and some “discoveries” tuned out wrong, nobody seems to be reading/reviewing or merging there at the moment

Possibly because

1. the original PR was closed, so the threat of breaking SpecialFunctions is not that imminent,

2. it requires quite a bit of investigation to find out the rationale for this PR.

You should compose the PR message so that a person reading it for the first time, unaware of any context or history (these can be referenced later), can understand

1. the motivation (why change)
2. the implementation (what changed),
3. and the benefits.

[Previous page](https://discourse.julialang.org/t/ann-anyone-need-my-2-7x-faster-factorial-or-gamma-function/19926.md?page=1)
