Q:

(Julia 1.x) Increased allocations by initialising variables?

A programme I am writing has a user-written file containing parameters which are to be read in and implemented within the code. Users should be able to comment their input file by delimiting them with a comment character (I have gone with "#", in convention with Julia) - in parsing the input file, the code will remove these comments. Whilst making minor optimisations to this parser, I noted that instantiating the second variable prior to calling split() made a noticeable difference to the number allocations:
function removecomments1(line::String; dlm::String="#")
    str::String = ""

    try
        str, tmp = split(line, dlm)
    catch
        str = line
    finally
        return str
    end
end

function removecomments2(line::String; dlm::String="#")
    str::String = ""
    tmp::SubString{String} = ""

    try
        str, tmp = split(line, dlm)
    catch
        str = line
    finally
        return str
    end
end

line = "Hello world # my comment"
@time removecomments1(line)
@time removecomments2(line)

$>  0.016092 seconds (27.31 k allocations: 1.367 MiB)
    0.016164 seconds (31.26 k allocations: 1.548 MiB)

My intuition (coming from a C++ background) tells me that initialising both variables should have resulted in an increase in speed as well as minimising further allocations, since the compiler has already been told that a second variable is required as well as its corresponding type, however this doesn't appear to hold. Why would this be the case?
Aside: Are there any more efficient ways of achieving the same result as these functions?
EDIT:
Following a post by Oscar Smith, initialising str as type SubString{String} instead of String has reduced the allocations by around 10%:
$>  0.014811 seconds (24.29 k allocations: 1.246 MiB)
    0.015045 seconds (28.25 k allocations: 1.433 MiB)

A:

In your example, the only reason you need the try-catch block is because you're trying to destructure the output of split even though split will return a one element array when the input line has no comments. If you simply extract the first element from the output of split, then you can avoid the try-catch construct, which will save you time and memory:
julia> using BenchmarkTools

julia> removecomments3(line::String; dlm::String = "#") = first(split(line, dlm))
removecomments3 (generic function with 1 method)

julia> @btime removecomments1($line);
  198.522 ns (5 allocations: 224 bytes)

julia> @btime removecomments2($line);
  208.507 ns (6 allocations: 256 bytes)

julia> @btime removecomments3($line);
  147.001 ns (4 allocations: 192 bytes)

In partial answer to your original question, pre-allocation is mainly used for arrays, not for strings or other scalars. For more discussion of when to use pre-allocation, check out this SO post.

