Vcat vs push!, which one is more efficient

Hi everybody,
I’m still a Julia newbie, so don’t be angry at me for silly questions.

I’m wondering whenever I should use vcat or push! to append elements to arrays. For example, let’s say I have one array
a = zeros(100)
and I want to append an element equal to 1, should I use a = vcat(a,[1]) or push!(a,1)?

At a first glance, it seems the same, but if I try to iterate this process, i.e. I want to append 100 times different elements, which are not given a priori (for simplicity, assume we always append 1), push! seems to be faster than vcat.

If, instead, the elements are given a priori, then concatenating the two arrays using once vcat seems to be faster than iteratively using push! to append elements of the second array to the first.

What it the reason behind this behavior?

Thanks!

They do different things; vcat creates a new array, push! modifies the array. It sounds like you want push! (or append!).

6 Likes

In the second case, use append!(a, b) to modify a by concatenating b to it. That should be as fast as or faster than vcat.

push! and append! are designed to be “cheap” in the amortized sense: arrays typically have some extra capacity beyond their current length, which can be used to add more elements without extra memory allocation. If that extra capacity is not enough, Julia may try to see if there is unused memory right after the array, in which case it can extend the array without copying the existing data into other place, which, again, is cheaper than moving all data on each operation. That makes push! and append! complexity “amortized linear” in number of added elements.

vcat, on the other hand, is “pure” function, i.e. it does not modify the object passed to it but allocates a new array each time and copies the data. Hence, if you add elements by one via vcat, then the complexity is quadratic in number of added elements.

2 Likes

Thank you very much, this explanation made things more clear. Then, in my case, I should use push! (since I do not have a priori knowledge of the second array).