У меня есть набор небольшого количества функций.Две функции выполняют математическую операцию наложения (определенную на http://docs.gimp.org/en/gimp-concepts-layer-modes.html,, но немного внизу - просто ищите «наложение», чтобы найти математику) по-разному.Теперь эта операция - то, что Gimp выполняет очень быстро, менее чем за секунду, но я не могу оптимизировать свой код, чтобы получить что-то похожее на удаленно похожее время.
(Мое приложение - это приложение с графическим интерфейсом, чтобы помочья вижу и сравниваю различные комбинации наложения большого количества файлов. Интерфейс слоя Gimp на самом деле делает довольно сложным просто выбрать два изображения для наложения, затем выбрать другое два и т. д.)
Вот код:
(set! *warn-on-reflection* true )
(defn to-8-bit [v]
(short (* (/ v 65536) 256)))
(defn overlay-sample [base-p over-p]
(to-8-bit
(* (/ base-p 65536)
(+ base-p
(* (/ (* 2 over-p) 65536)
(- 65536 base-p))))))
(defn overlay-map [^shorts base ^shorts over]
(let [ovl (time (doall (map overlay-sample ^shorts base ^shorts over)))]
(time (into-array Short/TYPE ovl))))
(defn overlay-array [base over]
(let [ovl (time (amap base
i
r
(int (overlay-sample (aget r i)
(aget over i)))))]
ovl))
overlay-map и overlay-array выполняют одну и ту же операцию разными способами.Я написал и другие версии этой операции.Однако overlay-map, безусловно, самый быстрый из всех, что у меня есть.
base и over, в обеих функциях - это 16-битные целочисленные массивы.Фактический размер каждого составляет 1 276 800 сэмплов (изображение 800 x 532 с 3 сэмплами на пиксель).Конечный результат должен быть одним и тем же массивом, но уменьшенным до 8 бит.
Мои результаты операции (времени) довольно последовательны.overlay-map выполняет фактическую математическую операцию примерно за 16 или 17 секунд, затем тратит еще 5 секунд, копируя полученную последовательность обратно в целочисленный массив.
overlay-array занимает около 111 секунд.
Я много читал об использовании массивов, подсказок типов и т. Д., Но моя операция только с Java-массивом удивительно медленная!amap, aget и т. д. должны были быть быстрыми, но я прочитал код, и нет ничего похожего на оптимизацию скорости, и мои результаты согласуются.Я даже пробовал другие компьютеры и видел примерно такую же разницу.
Теперь, 16-17 секунд, на самом деле довольно болезненно для этого набора данных, но я кеширую результаты, чтобы я мог легко переключатьсяназад и вперед.Эта же операция заняла бы ужасно много времени, если бы я увеличил размер набора данных до чего-то похожего на полноразмерное изображение (4770x3177).И есть и другие операции, которые я тоже хочу делать.
Итак, есть предложения, как это ускорить?Что мне здесь не хватает?
ОБНОВЛЕНИЕ: Я только что сделал весь проект, относящийся к этому коду, общедоступным, чтобы вы могли видеть текущую версию всего скрипта, который я использую для тестов скорости, на https://bitbucket.org/savannidgerinel/hdr-darkroom/src/62a42fcf6a4b/scripts/speed_test.clj.Не стесняйтесь загружать его и пробовать на своем оборудовании, но перед запуском явно измените пути к файлу изображения.