我正在尝试使用 Clojure 处理图像,并且我想使用 Clojure 数据结构表示图像。基本上,我的第一种方法是使用向量向量并对mapv
每个像素值进行操作并返回具有相同数据结构的新图像表示。但是,一些基本操作需要花费太多时间。
使用 Jvisual profiler,我得到了如下所示的结果。有人可以给我一个提高性能的提示吗?如果有必要,我可以提供更多详细信息,但也许只是看看成本,seq
有人next
可以有一个很好的猜测。
我正在尝试使用 Clojure 处理图像,并且我想使用 Clojure 数据结构表示图像。基本上,我的第一种方法是使用向量向量并对mapv
每个像素值进行操作并返回具有相同数据结构的新图像表示。但是,一些基本操作需要花费太多时间。
使用 Jvisual profiler,我得到了如下所示的结果。有人可以给我一个提高性能的提示吗?如果有必要,我可以提供更多详细信息,但也许只是看看成本,seq
有人next
可以有一个很好的猜测。
您应该查看core.matrix和相关的库以了解与矩阵计算有关的任何内容。core.matrix 是用于矩阵计算的通用 Clojure API,支持多种后端实现。
Clojure 的持久数据结构非常适合大多数用途,但实际上不适合快速处理大型矩阵。主要问题是:
您可能想要查看的相关库是:
根据您想要做什么,最好的方法可能是使用 image-matrix 将图像转换为 vectorz-clj 矩阵并在那里进行处理。或者,Clisk 可能能够做你想要的开箱即用(它有很多现成的过滤器/失真效果等)
免责声明:我是上述大多数库的首席开发人员。但是我自己将它们全部用于严肃的工作,因此非常愿意保证它们的有用性并帮助解决您发现的任何问题。
我真的认为你应该为此使用原语数组。Clojure 具有内置的数组支持,即使它没有突出显示,它适用于像这样的情况,在这种情况下你有大量的数值数据。
任何其他方法、向量,甚至 java 集合都会导致您的所有数字都被单独装箱,这是非常浪费的。原语数组(int、double、byte,任何合适的)都没有这个问题,这就是它们存在的原因。人们对在 clojure 中使用数组感到害羞,但他们在那里是有原因的,就是这样。这将是一个很好的可移植的 clojure 代码——int-array 在 jvm clojure 和 clojure-script 中都有效。
尝试数组和基准测试。
Clojure 的瞬态提供了完全持久性和无持久性之间的中间地带,就像使用标准 java 数组一样。这允许您使用快速就地变异操作(仅限于当前线程)来构建图像,然后调用persistent!
以在恒定时间内将其转换为适当的持久结构,以便在程序的其余部分进行操作
看起来您还看到在图像内容上使用序列会产生很多开销,如果瞬态没有产生足够的差异,您接下来可能要考虑使用普通的 java 数组并构造访问以直接访问数组元素。