Most imperative programming languages come with dynamic arrays that promise amortized O(1) appends. There is no magic though and this dynamism always come at a cost. That’s why these data structures usually come with a way to reserve storage in advance to avoid unnecessary memory reallocations and copies.
In C++ this can be achieved using std::vector::reserve
and in this particular case it enables 1.2X faster runtime performance
but it can be much bigger improvement for vectors with items that are expensive or impossible to move.
But what about Python? I often see generation code like
which clearly doesn’t provide runtime with information about final size. And unlike std::vector, it doesn’t seem like there is an API to reserve storage. So are we out of options? Not really, we can use either
to create a list of n zeroes that is populated with resulting values or better yet - use list comprehensions
I don’t think there would be any disagreement around which option is most readable, but what about performance?
So looks like both proposals provide better performance and since list comprehensions are also super readable, I’d recommend always considering it as a first choice.
You can explore this example in colab. Compiler explorer can be used to see the generated bytecode.