У меня есть набор небольшое количество функций. Две функции выполняют операцию математического наложения (определенную на 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 и более в обеих функциях представляют собой массивы 16-битных целых чисел. Фактический размер каждого составляет 1 276 800 сэмплов (изображение 800 x 532 с 3 сэмплами на пиксель). Конечным результатом должен быть один такой же массив, но уменьшенный до 8 бит.
Мои результаты операции (время) довольно последовательны. overlay-map выполняет фактическую математическую операцию примерно за 16 или 17 секунд, а затем тратит еще 5 секунд на копирование полученной последовательности обратно в целочисленный массив.
оверлей-массив занимает около 111 секунд.
Я много читал об использовании массивов, подсказках типов и т. Д., Но моя операция Java-Array-Only выполняется на удивление медленно! amap, aget и т. д. должны были быть быстрыми, но я прочитал код, и нет ничего похожего на оптимизацию скорости, и мои результаты согласуются. Я даже пробовал другие компьютеры и видел примерно такую же разницу.
Итак, 16-17 секунд, на самом деле, довольно болезненно для этого набора данных, но я кэшировал результаты, чтобы я мог легко переключаться туда и обратно. Та же операция заняла бы ужасно много времени, если бы я увеличил размер набора данных до чего-нибудь вроде полноразмерного изображения (4770x3177). И есть другие операции, которыми я тоже хочу заниматься.
Итак, есть какие-нибудь предложения, как это ускорить? Что мне здесь не хватает?
ОБНОВЛЕНИЕ: Я только что опубликовал весь проект, относящийся к этому коду, поэтому вы можете увидеть всю текущую версию скрипта, который я использую для тестов скорости, на https://bitbucket.org/ savannidgerinel / hdr-darkroom / src / 62a42fcf6a4b / scripts / speed_test.clj .Не стесняйтесь загрузить его и попробовать на своем собственном оборудовании, но, очевидно, измените пути к файлам изображений перед запуском.