# How do I efficiently copy or move elements from one vector to another?

I'm working on optimizing some Emacs Lisp code that I've written. Part of this code needs to move elements from one vector to another. Currently, I have this code:

(defun copy-elements (source source-begin source-end
destination destination-begin)
"Copy elements from SOURCE to DESTINATION.

We start at SOURCE[SOURCE-BEGIN], and the last element copied is
SOURCE[SOURCE-END - 1].

These elements are copied beginning at DESTINATION[DESTINATION-BEGIN].
This means DESTINATION must have enough space.

This method returns DESTINATION, and does not modify SOURCE.

If SOURCE and DESTINATION are the same, overlapping could cause issues."
(dotimes (i (- source-end source-begin))
(setf (seq-elt destination (+ i destination-begin))
(seq-elt source (+ source-begin i))))
destination)


This works fine:

ELISP> (let ((v1 [1 2 3]) (v2 [4 5 6])) (copy-elements v1 0 1 v2 2) (list v1 v2))
([1 2 3]
[4 5 1])


But it's not as efficient as it could be. Even though we know we're working on consecutive elements, we move each one separately.

Is there a way to move or copy these elements? I don't need to share structure, so copying them would be perfectly fine if that's more efficient.

In fns.c, the function copy-sequence uses the C function memcpy to move things around vectors, but I don't see a way to do that myself.

What can I do to speed up moving consecutive elements from one vector to another?

• The seq.el API is generalised over all sequence types so will always be less efficient than vector-specific operations, so prefer aref and aset over setf-ing seq-elt. In idiomatic Elisp, there is usually no need for memcpy-like operations. Instead, you can efficiently create a copy of a subvector using the built-in function substring, or efficiently join subvectors using the built-in function vconcat. Jan 29, 2020 at 8:40
• substring with a vector argument is pretty hidden in the documentation if you're trying to learn about vectors. They're both array types, but even so... that's pretty obtuse even by lisp standards. Jan 29, 2020 at 9:14
I don't think there's such a thing and using memcpy on incompatible types is risky, so I went for the dumb solution in my last emulator project:
(defun chip8--memcpy (dest dest-offset src src-offset n)