# New find\* methods and type stability

**URL:** <https://discourse.julialang.org/t/new-find-methods-and-type-stability/8722>\
**Category:** General Usage\
**Created:** [January 31, 2018, 6:44pm UTC](https://discourse.julialang.org/t/new-find-methods-and-type-stability/8722 "2018-01-31T18:44:33Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![jmkuhn](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jmkuhn/32/2090_2.png) [@jmkuhn](https://discourse.julialang.org/u/jmkuhn)\
**Post date:** [January 31, 2018, 6:44pm UTC](https://discourse.julialang.org/t/new-find-methods-and-type-stability/8722/1 "2018-01-31T18:44:34Z")

</div>

In 0.7 find\* methods changed the return value from 0 to `nothing` for no match. Assuming the following code is in a function:

```julia
s = "abc"
pos = findfirst(equalto('b'), s)
println(typeof(pos))
pos = findfirst(equalto('x'), s)
println(typeof(pos))

```

The type of `pos` changes from `Int` to `Nothing`. Will this type instability cause performance issues? Should I declare pos with type `Union{Nothing, Int}`?

---

<div class="post-metadata">

**Author:** ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)\
**Post date:** [January 31, 2018, 7:00pm UTC](https://discourse.julialang.org/t/new-find-methods-and-type-stability/8722/2 "2018-01-31T19:00:16Z")

</div>

The compiler is pretty good at these types of type instabilities. So benchmark your code and unless you notice a problem, just done worry about it.

---

<div class="post-metadata">

**Author:** ![foobar\_lv2](https://avatars.discourse-cdn.com/v4/letter/f/ee59a6/32.png) [@foobar\_lv2](https://discourse.julialang.org/u/foobar_lv2)\
**Post date:** [January 31, 2018, 11:09pm UTC](https://discourse.julialang.org/t/new-find-methods-and-type-stability/8722/3 "2018-01-31T23:09:36Z")

</div>

Hmm. The following looks like it regresses quite severely:

```julia
versioninfo()
#Julia Version 0.6.2
using BenchmarkTools

struct equalto_{T} <: Function
       x::T
end
(eq_::equalto_{T})(y) where T = isequal(eq_.x, y)

V=[rand(UInt8, rand(0:255)) for i=1:1000];
Q=rand(UInt8, 1000);

function foolistsearch6(Q, V)
     out = Vector{Int}(length(V))
     for i=1:length(V)
           pos = findfirst(equalto_(Q[i]), V[i])
               if pos===0
                    out[i]=-1
               else
                    out[i]=pos
               end
     end
     out
 end
@btime foolistsearch6(Q,V);
#115.033 ��s (1 allocation: 7.94 KiB)
Q=rand(UInt16, length(Q));
@btime foolistsearch6(Q,V);
#148.848 ��s (1 allocation: 7.94 KiB)

```

```julia
versioninfo()
#Julia Version 0.7.0-DEV.3666
#Commit 0f95988141* (2018-01-31 03:25 UTC)
using BenchmarkTools

V=[rand(UInt8, rand(0:255)) for i=1:1000];
Q=rand(UInt8, 1000);

function foolistsearch7(Q, V)
     out = Vector{Int}(length(V))
     for i=1:length(V)
           pos = findfirst(equalto(Q[i]), V[i])
               if pos===nothing
                    out[i]=-1
               else
                    out[i]=pos
               end
     end
     out
 end

@btime foolistsearch7(Q,V)
154.900 ��s (88 allocations: 19.52 KiB)
Q=rand(UInt16, length(Q));
@btime foolistsearch7(Q,V)
287.831 ��s (88 allocations: 19.52 KiB)

```

I am not sure whether my example code simply sucks, or my example is badly chosen or whether this is due to the new handling.

---

<div class="post-metadata">

**Author:** ![rdeits](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rdeits/32/286_2.png) [@rdeits](https://discourse.julialang.org/u/rdeits)\
**Post date:** [February 1, 2018, 2:17am UTC](https://discourse.julialang.org/t/new-find-methods-and-type-stability/8722/4 "2018-02-01T02:17:46Z")

</div>

I’d suggest trying on the latest Julia master. The performance improvements for small unions are new in v0.7.

---

<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:** [February 1, 2018, 3:00am UTC](https://discourse.julialang.org/t/new-find-methods-and-type-stability/8722/5 "2018-02-01T03:00:17Z")

</div>

They both are on 0.7. @foobar_lv2 — you have a deprecated method in your version 7 example. Changing `Vector{Int}(length(V))` to `Vector{Int}(uninitialized, length(V))` gives me nearly a 4x speed up.

Deprecations are slow. Fix that and 0.7 is way faster in my tests.

---

<div class="post-metadata">

**Author:** ![foobar\_lv2](https://avatars.discourse-cdn.com/v4/letter/f/ee59a6/32.png) [@foobar\_lv2](https://discourse.julialang.org/u/foobar_lv2)\
**Post date:** [February 1, 2018, 1:13pm UTC](https://discourse.julialang.org/t/new-find-methods-and-type-stability/8722/6 "2018-02-01T13:13:11Z")

</div>

Ok, you’re right. Somehow I naively thought that deprecations would only show warnings and induce slow-down during compilation.

The new timings are:

```julia
  21.713 ��s (1 allocation: 7.94 KiB)
 152.476 ��s (1 allocation: 7.94 KiB)

```

which is indeed way faster than 0.62. I hereby retract all my objections 🙂

PS at rddeits: You see from the versionstring that my 0.7 version was a master less than 48 hours old. I shall continue to post `versioninfo()` for all timings (master is moving so fast).

---

<div class="post-metadata">

**Author:** ![rdeits](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rdeits/32/286_2.png) [@rdeits](https://discourse.julialang.org/u/rdeits)\
**Post date:** [February 1, 2018, 5:11pm UTC](https://discourse.julialang.org/t/new-find-methods-and-type-stability/8722/7 "2018-02-01T17:11:27Z")

</div>

Ah yes, I missed that, sorry.
