Maybe it is subtle but AFAICT this operation is O(N + M) where N is the number of elements in the sequence and M the number of elements that are inserted.
Let’s make the problem more concrete: Given a sequence with O(N) elements, insert M elements from a Stream [*] into the sequence in O(M).
If you use vectors, and insert the elements one by one, you get O(N * M) complexity, because for each element from the Stream that you insert, you have to shift N vector elements. Here it is much better to do what your iterator code is doing: insert M elements into a separate vector which is amortized O(1) per element, and then you insert that vector into the original one once the Stream has been exhausted. This results in O(N + M) complexity and requires O(M) extra storage.
With a doubly-linked list, you have to find the middle once, which is O(N), but then all insertions are O(1). So you get O(N+M) complexity. However, depending on how you see things, finding the middle is amortized over the M insertions, so you could also argue that inserting is amortized O(1), and this takes O(M) time for a list. Also, if you already have a pointer to the middle stored somewhere, this is unarguably an O(M) operation. So for a list, it makes a bit of a difference whether you have a pointer to the insertion point lying around or not.
Using the Stream here is not necessary. If you have the elements in a vector already, inserting into a vector is still O(N + M), but again inserting into a list can be O(N+M) or O(M) depending on whether you have a pointer to the middle around or not. What the Stream shows is that with a list you don’t need extra storage. You also don’t need multiple passes to implement this operation, which can be important, for example, if concurrency is involved (although in that case a “normal” list won’t work).
Also, things change even further if instead of having the elements to insert in a vector, you already have them in a list, because then inserting into a vector is still O(N + M) but inserting them into another list is O(N), or if you have a pointer to the insertion point lying around: O(1).
Or in other words, if you can a priori have a pointer to the insertion point and reuse it, inserting into a vector is always O(N + M), but inserting into a list is either O(M) or O(1). This can and is much faster than inserting into a vector, particularly if N is large and M is small. OTOH if you don’t have a pointer to the insertion point, then this becomes O(N + M) and O(N) for the list, in which case the fastest solution will depend on the “list traversal cost” vs the “vector memcpy cost”.
The take away here isn’t that list can be faster than vector, or that vector is often/generally faster than list, but that for lists having a pointer to the insertion/splicing/erasing point makes a huge difference performance wise. If a list API does not support this, then you are better off just using a vector because this is the main advantage of lists.
[*] That is, the number of elements to be inserted is a priori unknown, one only knows M once the Stream has been exhausted.