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?