I have been trying to rewrite a python script I wrote a while back in julia to increase its performance. The python script used a package called gym-retro which ran a videogame emulator that the script could directly interact with. As far as I am aware, there is no Julia equivalent so I am importing gym-retro using PyCall. Game information such as the current frame and RAM are outputted as numpy arrays. My attempts to read the data from these arrays have been incredibly slow and memory inefficient. For example, if I run this code:
function index_test(pyarray::PyArray{UInt8, 3})
a = pyarray[1, 1, 1]
end
function conversion_test(pyarray::PyArray{UInt8, 3})
converted_frame = convert(Array{UInt8, 3}, pyarray)
end
function reset(arcade::Arcade)
frame = pycall(arcade.env.reset, PyArray)
println(typeof(frame))
println(size(frame))
@btime index_test($frame)
@btime conversion_test($frame)
end
It outputs this response in the REPL:
PyArray{UInt8, 3}
(224, 240, 3)
308.230 ns (14 allocations: 416 bytes)
184.150 ms (5653541 allocations: 182.49 MiB)
I am unsure as to why indexing the array causes 14 allocations. This is bottle-necking my program as I can only process a maximum of 5 frames per second. Any advice on how I can more efficiently index data from a PyArray would be greatly appreciated.
EDIT: Here are the results if I use the view()
function:
function view_test(pyarray::PyArray{UInt8, 3})
a = view(pyarray, 1, 1, 1)
end
function reset(arcade::Arcade)
frame = pycall(arcade.env.reset, PyArray)
@btime view_test($frame)
end
806.977 ns (16 allocations: 336 bytes)