If you create an empty tensor, then give it as out=, then it will be resized and filled with the result. This will be the same as c = a + 3 in your first example.
Doing c[:] = a + 3 will create an intermediary result and copy it into c (which will work only if c has been resized beforehand).
If can be usefull to prevent your operation to create a new tensor if you already have a Tensor of the right size that is not needed anymore.
Unless you work with very large Tensors or very specific use case, the performance gain is not going to be noticeable.