# Function uses huge memory

I can not figure out as to why the function given below uses huge memory allocations.

``````function findpi(n::Int64)::Float64
inside = 0
x,y=0.0,0.0
for i in 1:n
x, y = rand(2)

inside += (x^2 + y^2) <= 1 ? 1 : 0
end
4 * inside / n
end

@time findpi(10000000)
@time findpi(10000000)
@time findpi(10000000)

0.556831 seconds (10.04 M allocations: 917.497 MiB, 11.59% gc time)
0.461873 seconds (10.00 M allocations: 915.528 MiB, 10.93% gc time)
0.486833 seconds (10.00 M allocations: 915.528 MiB, 11.24% gc time)
``````

Don’t mix Int and Float64 in the calculations.

Here is an alternative

``````julia> function findpi(n)
inside = 0.
for i in 1:n
inside += rand()^2 + rand()^2 <= 1 ? 1. : 0.
end
4 * inside / n
end
findpi (generic function with 1 method)

julia> @benchmark findpi(10000000)
BenchmarkTools.Trial:
memory estimate:  0 bytes
allocs estimate:  0
--------------
minimum time:     43.458 ms (0.00% GC)
median time:      44.101 ms (0.00% GC)
mean time:        44.429 ms (0.00% GC)
maximum time:     54.051 ms (0.00% GC)
--------------
samples:          113
evals/sample:     1
``````
1 Like

Thank you both @LeoK987 and @jbrea for your quick and wonderful response.

`rand(2)` allocates a vector, which you deconstruct immediately
`x,y = rand(), rand()` should solve that problem.

5 Likes

Also note that the mixing of float and Int was not a problem in your original code. Everything was type stable, as `inside` started out as an int and stayed an Int.

6 Likes

Thanks @baggepinnen.

It seems like we are missing a generator version of `rand(N)`.

1 Like
``````a, b, c, d, e = Iterators.cycle((randn() for i in 1));
``````

works.

1 Like

In this case they were not mixed. And, in general, there’s nothing wrong with mixing them, either.

Using floats is not optimal here. Use `Int`s, like this:

``````function findpi2(n)
inside = 0
for i in 1:n
inside += rand()^2 + rand()^2 <= 1 ? 1 : 0
end
return 4 * inside / n
end
``````

or, equally fast (but more elegant, IMHO):

``````function findpi3(n)
inside = 0
for i in 1:n
inside += (rand()^2 + rand()^2 <= 1)
end
return 4 * inside / n
end
``````
``````julia> @btime findpi(10^7)
38.940 ms (0 allocations: 0 bytes)
3.1421128

julia> @btime findpi2(10^7)
32.242 ms (0 allocations: 0 bytes)
3.1416336

julia> @btime findpi3(10^7)
32.220 ms (0 allocations: 0 bytes)
3.1418104
``````
2 Likes

@DNF Thanks