Hello everyone, I am very much new to Julia trying to understand how allocations work and how to reduce them. I am writing a small program that reads some files, processes the data and outputs the results. Hence I am reading files line by line and I came across a curious behavior that I cannot explain myself and struggle to find answers to online.
I have a function that takes an index i, a (static) vector sys_size that has some needed information and another vector pos that is set using the other arguments. I have tested this in the REPL that this runs without any allocations (the vectors are of length 2 or 3).
function set_pos!(i, pos, sys_size)
D = length(sys_size)
pos[D] = i
for i in D:-1:2
x, y = fldmod1(pos[i], sys_size[i])
pos[i] = y
pos[i-1] = x
end
end
Now I want to use this in my main loop over the file that is itself in a function and looks as
for (line_i, line) in enumerate(eachline(joinpath(dir_path, fname)))
set_pos!(line_i, pos, sys_size)
end
which has allocations of ~2 times the number of lines in the file. When testing this I have ran the same loop without a body (empty) which results in half the allocations and from further testing via the equivalent loop at the end of the post I conclude there is ~1 allocation per iteration coming just from building a String, this makes sense, that means there seems to be an additional 1 allocation per iteration coming from the set_pos! function and that I do not understand.
To further test this I have tried running the loop
for (line_i, line) in enumerate(eachline(joinpath(dir_path, fname)))
set_pos!(1, pos, sys_size)
end
instead, simply replacing the integer variable by a constant. This somehow reduces the allocations to ~1 per iteration, same as if it had an empty body. This very much confuses me as line_i is just an integer and all I change is which integer is passed to the function. I would greatly appreciate any help with understanding this.
Alternative, more bare-bones but equivalent loop that I also used for testing (it reproduces the same results):
file = open(joinpath(dir_path, fname))
line_i = 1
while !eof(file)
line = readline(file)
set_pos!(line_i, pos, sys_size)
line_i += 1
end