有一种快速的方法可以使用Clojure向量作为矩阵吗?

boe*_*107 2 performance profiling clojure

我正在尝试使用Clojure处理图像,我想使用Clojure数据结构来表示图像.基本上,我的第一种方法是使用向量矢量并对mapv每个像素值进行操作并返回具有相同数据结构的新图像表示.但是,一些基本操作需要花费太多时间.

使用Jvisual profiler,我得到的结果如下所示.有人可以给我一个改善表现的小费吗?我可以提供更多的细节,如果有必要,但也许只是在寻找的成本seq,并next有人能有一个很好的猜测.

分析向量矢量的运算结果.

mik*_*era 7

你应该检查core.matrix和相关的库,以便与矩阵计算有关.core.matrix是用于矩阵计算的通用Clojure API,支持多个后端实现.

Clojure的持久数据结构非常适合大多数用途,但实际上并不适合快速处理大型矩阵.主要问题是:

  • 不可变性:通常是一件好事,但对于低级代码可能是一个杀手,你需要做一些事情,比如因为性能原因而在可变数组中累积结果.
  • 拳击:Clojure数据结构一般是盒子结果(如java.lang.Double等),与使用原语相比,它增加了很多开销
  • 序列:遍历大多数Clojure数据结构作为序列涉及创建临时堆对象以保存序列元素.通常不是问题,但是当你处理大型矩阵时,它会成为问题.

您可能想要查看的相关库是:

  • vectorz-clj:一个非常快速的矩阵库,可以作为一个完整的core.matrix实现.底层代码是纯Java,但有一个很好的Clojure包装器.我相信它是目前在Clojure中进行通用矩阵计算的最快方法,而不需要使用本机代码.在引擎盖下,它使用Java原语数组,但您不需要直接处理它.
  • Clatrix:Clojure的另一个快速矩阵库,也是core.matrix实现.引擎盖下使用JBLAS.
  • image-matrix:表示Java BufferedImage作为core.matrix实现,因此您可以对图像执行矩阵操作.现在有点实验,但应该适用于基本用例
  • Clisk:用于程序图像处理的库.与基质库本身无关,但对于使用基于Clojure的DSL创建和操作数字图像非常有用.

根据您的想法,最好的方法可能是使用图像矩阵将图像转换为vectorz-clj矩阵并在那里进行处理.或者,Clisk可能能够开箱即用(它有很多现成的滤镜/失真效果等).

免责声明:我是上述大多数图书馆的首席开发人员.但是我自己一直在使用它们来做认真的工作,所以非常愿意保证它们的实用性,并帮助解决你发现的任何问题.