Нужны функции, выполняющие арифметические операции как над числами, так и над последовательностями. Определяю так:
(defgeneric opAdd (x y))
(defmethod opAdd ((x number) (y number))
(+ x y))
(defmethod opAdd ((xs list) (y number))
(mapcar (lambda (x) (+ x y)) xs))
(defmethod opAdd ((xs array) (y number))
(map 'vector (lambda (x) (+ x y)) xs))
Но на простом тесте (opAdd число число) в 20 раз проигрывал простому суммированию:
(let ((xs (make-array 10000 :initial-element 1 :element-type 'number))
(ys (make-array 10000 :initial-element 2 :element-type 'number)))
(time (dotimes (i 1000)
(map nil #'opAdd xs ys)))) ; и #'+ вместо #'opAdd
Причем, если добавить методы opAdd по работе с другими классами, то время выполнения теста немного увеличивается, т.е. получается, что компилятор, несмотря на явное указание типа элемента массива, просматривает все методы, соответствующие вызову opAdd.
Для того, чтобы повысить скорость, добавил compiler-макрос, который пытается подставить обычное суммирование вместо генерик-функции, если аргументы являются числами:
(define-compiler-macro opAdd (&whole form x y)
(if (and (numberp x) (numberp y))
`(+ ,x ,y)
form))
Но на времени исполнения теста это никак не сказалось. Единственно, что получилось — явно указать использование compiler-макроса:
(let ((compose-form (funcall (compiler-macro-function 'opAdd)
'(opAdd x y)
nil)))
(let ((opAdd (funcall (compile nil `(lambda () (defun opAdd (x y) ,compose-form))))))
(let ((xs (make-list 10000 :initial-element 1))
(ys (make-list 10000 :initial-element 2)))
(time (dotimes (i 1000)
(map nil #'opAdd xs ys))))))
Время исполнения этого теста уже только в 4 раза больше, чем явное использование #'+
Есть ли, какой-нибудь способ подсказать компилятору по возможности использовать стандартные арифметические функции вместо генерик-функции, не меняя при этом код вызова?
Ответ на:
комментарий
от mv
Ответ на:
комментарий
от anonymous
Ответ на:
комментарий
от anonymous
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.
Похожие темы
- Форум [common lisp][ищу морфизм] ещё одна годная задачка про списки (2010)
- Форум Произвольные классы методов для дженериков (2014)
- Форум Ltk не могу понять, что не работает (2019)
- Форум Выясняем с помощью Emacs, какой ЯП лучше (2024)
- Форум elisp (2011)
- Форум сделал неработоспособную конфигурацию Emacs (2017)
- Форум Lisp Macro (2007)
- Форум puzzle in mcclim (2019)
- Форум [FFI] CL крут (2010)
- Форум company-jedi emacs виснет (2016)