Hello All, I am new to Julia and working on below code in Julia and similar one in Python, Java.
But, Julia code is slower than Python and 10x slower than Java code. Can you please let me know how to optimize below code in Julia.
Problem statement:
Matrix (2D array) is filled with ones (represents personos) and zeros (represents bikes). A person can move top, bottom, left or right. We need to find out the nearest bike to him.
Solution that I wrote -
#1 - O(n2) - First iterate over matrix and prepare two seperate lists bikes and persons with their positions (row/x, col/y).
#2. O(n2) - In a nested for loop, iterate over persons and bikes list and find the distance between those two Positions to know the shortest distance between them and replace the person with least distance value.
Distance formula: abs(x1-x2) + abs(y1-y2) where Person=(x1, y1) and Bike=(x2, y2).
This solution take 5 sec in Java for 100x100 size, Python 15secs, Julia 16secs.
If I increase the size to 500, Java is 10x faster than Julia.
import Dates
import StatsBase.sample
import StatsBase.ProbabilityWeights
struct Position
x::Int32
y::Int32
val::Int8
end
matrix = sample([0,1], ProbabilityWeights([1/6, 5/6]), (100, 100))
matrix_test = sample([0,1], ProbabilityWeights([1/6, 5/6]), (10, 10))
function prepare_persons_bikes(matrix)
rows, cols = size(matrix)
persons = []
bikes = []
for x in 1:rows
for y in 1:cols
pos = Position(x, y, matrix[x, y])
if pos.val == 1
push!(persons, pos)
else
push!(bikes, pos)
end
end
end
println("Size of persons=$(length(persons)), bikes=$(length(bikes))")
return (persons, bikes)
end
function find_distance(matrix, persons, bikes)
for (idx, person) in enumerate(persons)
nearest_distance = abs(person.x-bikes[1].x) + abs(person.y-bikes[1].y)
for bike in bikes[2:end]
dist = abs(person.x-bike.x) + abs(person.y-bike.y)
if dist < nearest_distance
nearest_distance = dist
end
if nearest_distance == 1
break
end
end
matrix[person.x, person.y] = nearest_distance
if idx % 1000 == 0
println("Processed=$idx, $(Dates.now())")
flush(stdout)
end
end
end
function find(matrix)
rows, cols = size(matrix)
if rows < 10 && cols < 10
display(matrix)
end
persons, bikes = prepare_persons_bikes(matrix)
@time begin
find_distance(matrix, persons, bikes)
end
if rows < 10 && cols < 10
display(matrix)
end
end
find(matrix_test)
find(matrix)