# Can this loop be optimized further?

**URL:** https://discourse.julialang.org/t/can-this-loop-be-optimized-further/32510
**Category:** Performance
**Tags:** question
**Created:** [December 20, 2019, 1:20pm UTC](https://discourse.julialang.org/t/can-this-loop-be-optimized-further/32510 "2019-12-20T13:20:02Z")
**Posts on this page:** 8
**Page:** 1

<div class="post-metadata">

### Author: ![Dictino](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dictino/32/217281_2.png) [@Dictino](https://discourse.julialang.org/u/Dictino)
#### Post date: [December 20, 2019, 1:20pm UTC](https://discourse.julialang.org/t/can-this-loop-be-optimized-further/32510/1 "2019-12-20T13:20:02Z")

</div>

I have this function to find an element in an array:

```julia
function my_findfirst(element,array)
    	for i=1:length(array)
        	if @inbounds (array[i]==element)
			return i
		end
	end
	return nothing
end

```

I’ve created this function to make it faster than `findfirst`, and it is already faster for some types:

```julia
N=100_000_000
array=zeros(Float64,N)
array[N÷2]=1.0

#first time run to compile
findfirst(isequal(1.0),array)
my_findfirst(1.0,array)

@time findfirst(isequal(1.0),array)
#0.143356 seconds (6 allocations: 192 bytes)

@time my_findfirst(1.0,array)
#0.079413 seconds (5 allocations: 176 bytes)

```

But for UInt8 is much slower:

```julia
N=100_000_000
array=zeros(UInt8,N)
array[N÷2]=UInt8(1)

#first time run to compile
findfirst(isequal(UInt8(1)),array)
my_findfirst(UInt8(1),array)

@time findfirst(isequal(UInt8(1)),array)
#0.008938 seconds (6 allocations: 192 bytes)

@time my_findfirst(UInt8(1),array)
#0.046022 seconds (5 allocations: 176 bytes)

```

So I see that there is some room to optimize 😉

Could you help me to make it faster please?

Thanks in advance!

---

<div class="post-metadata">

### Author: ![baggepinnen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/baggepinnen/32/693_2.png) [@baggepinnen](https://discourse.julialang.org/u/baggepinnen)
#### Post date: [December 20, 2019, 1:24pm UTC](https://discourse.julialang.org/t/can-this-loop-be-optimized-further/32510/2 "2019-12-20T13:24:25Z")

</div>

Try avoiding global variables in the code you are benchmarking and try to use Benchmarktools for more accurate benchmarks.

> **[GitHub - JuliaCI/BenchmarkTools.jl: A benchmarking framework for the Julia...](https://github.com/JuliaCI/BenchmarkTools.jl)**
>
> A benchmarking framework for the Julia language. Contribute to JuliaCI/BenchmarkTools.jl development by creating an account on GitHub.

---

<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: [December 20, 2019, 1:32pm UTC](https://discourse.julialang.org/t/can-this-loop-be-optimized-further/32510/3 "2019-12-20T13:32:05Z")

</div>

> [@baggepinnen](#):
>
> Try avoiding global variables in the code you are benchmarking and try to use Benchmarktools for more accurate benchmarks.

Don’t really think global or not will matter when the length is `100_000_000`

Regarding the question, Base has a special implementation for the specific case of finding `UInt8`:

> <https://github.com/JuliaLang/julia/blob/608567f8566363536042e7f73d84b8670fc910d4/base/strings/search.jl#L22-L39>

---

<div class="post-metadata">

### Author: ![baggepinnen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/baggepinnen/32/693_2.png) [@baggepinnen](https://discourse.julialang.org/u/baggepinnen)
#### Post date: [December 20, 2019, 2:07pm UTC](https://discourse.julialang.org/t/can-this-loop-be-optimized-further/32510/4 "2019-12-20T14:07:56Z")

</div>

> [@kristoffer.carlsson](#):
>
> Don’t really think global or not will matter when the length is `100_000_000`

No it probably won’t matter much in this case, but will show misleading allocations. It’s at least good practice to avoid it.

---

<div class="post-metadata">

### Author: ![Dictino](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dictino/32/217281_2.png) [@Dictino](https://discourse.julialang.org/u/Dictino)
#### Post date: [December 20, 2019, 2:09pm UTC](https://discourse.julialang.org/t/can-this-loop-be-optimized-further/32510/5 "2019-12-20T14:09:46Z")

</div>

Thanks for the advice and the fast response!  
The original versión was inside a module and the results are similar.  
I Will test with BenchmarkTools also 🙂

---

<div class="post-metadata">

### Author: ![Dictino](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dictino/32/217281_2.png) [@Dictino](https://discourse.julialang.org/u/Dictino)
#### Post date: [December 20, 2019, 2:15pm UTC](https://discourse.julialang.org/t/can-this-loop-be-optimized-further/32510/6 "2019-12-20T14:15:58Z")

</div>

> [@kristoffer.carlsson](#):
>
> ``
> 
> Regarding the question, Base has a special implementation for the specific case of finding `UInt8` :

Interesting… So possibly memchr is doing some clever low level tricks to be as fast…

I Will investigate 😉

Thanks Kristoffer!

---

<div class="post-metadata">

### Author: ![baggepinnen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/baggepinnen/32/693_2.png) [@baggepinnen](https://discourse.julialang.org/u/baggepinnen)
#### Post date: [December 20, 2019, 2:25pm UTC](https://discourse.julialang.org/t/can-this-loop-be-optimized-further/32510/7 "2019-12-20T14:25:33Z")

</div>

There is a global scope in the module as well. The variables have to be either constant or inside functions for you not to pay the prices of global access.

---

<div class="post-metadata">

### Author: ![Dictino](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dictino/32/217281_2.png) [@Dictino](https://discourse.julialang.org/u/Dictino)
#### Post date: [December 20, 2019, 2:51pm UTC](https://discourse.julialang.org/t/can-this-loop-be-optimized-further/32510/8 "2019-12-20T14:51:01Z")

</div>

I missunderstood this point…  
Thank you for the clarificarion.
