Производительность преобразования пикселей с использованием clojure и quil
Давайте предположим, что я хотел бы написать алгоритм ocr. Поэтому я хочу создать двоичное изображение. Используя clojure и quil, я придумал:
(defn setup []
(load-pixels)
(let [pxls (pixels)
]
(letfn [(pxl-over-threshold? [idx] (if (> (red (aget pxls idx)) 128) true false))
]
(time (dotimes [idx 25500] (aset pxls idx (color (rem idx 255)))))
(time (dotimes [idx 25500] (if (pxl-over-threshold? idx)
(aset pxls idx (color 255))
(aset pxls idx (color 0)))))))
(update-pixels))
(defn draw [])
(defsketch example
:title "image demo"
:setup setup
:draw draw
:size [255 100]
:renderer :p2d)
;"Elapsed time: 1570.58932 msecs"
;"Elapsed time: 2781.334345 msecs"
Код генерирует градации серого и затем перебирает все пиксели, чтобы установить их черным или белым. Он выполняет запрошенное поведение, но для этого требуется около 4,3 с (1,3-ядерное ядро). У меня нет ссылки, чтобы поставить 4,3 сек в контексте. Но если подумать об обработке большего изображения, это должно стать невероятно медленным.
Я делаю что-то ужасно неправильно или есть способ закрепить вещи? Способна ли комбинация clojure и quil быстрее преобразовывать пиксели или мне следует выбрать другой язык / среду?
Пожалуйста, дайте мне знать, если я делаю что-то странное в коде. Я все еще новичок в clojure.
Заранее спасибо.
1 ответ
Времена, которые вы взяли, не особенно значимы, потому что код еще не теплый. Вам нужно "прогреть" код, чтобы JVM JIT-компилировала его, и тогда вы должны начать видеть хорошую скорость. Вы должны взглянуть на Как тестировать функции в Clojure? (Вы должны использовать Критерий.)
Что касается вашего кода, вы используете массивы, так что это должно дать вам хорошую производительность. По стилю, два подвесных ]
у вас действительно странно. Может быть, это просто ошибка форматирования? Обычно хорошо удалять как можно больше повторяющегося кода, поэтому я бы также изменил это
(if (pxl-over-threshold? idx)
(aset pxls idx (color 255))
(aset pxls idx (color 0)))
к этому
(aset pxls idx (color (if (pxl-over-threshold? idx) 255 0)))
Если вы чувствуете, что выглядишь слишком запутанно / сложно (я вроде как на грани того, считаю ли я это слишком трудным для чтения или нет), вы можете вместо этого написать это одним из следующих способов:
(let [c (if (pxl-over-threshold? idx) 255 0)]
(aset pxls idx (color c)))
(->> (if (pxl-over-threshold? idx) 255 0) color (aset pxls idx))