我正在计算Clojure中3d点云的边界框。点云表示为Java基本浮点数组,点云中的每个点都使用4个浮点存储,其中最后一个浮点未使用。像这样:
[x0 y0 z0 u0 x1 y1 z1 u1 .... ]
点云的大小为19200,即阵列中的浮点数为4*19200。
其中一些值可能不是有限的(要么是无限的,要么是NaN)。因此,任何包含非有限值的点都应完全排除在计算之外。我已经在Java和Clojure中实现了这个计算,但由于某种原因,Clojure版本仍然要慢4到5倍。
Clojure代码是这样的:
(defn good-compute-bbox [^floats data]
(let [n (alength data)]
(loop [i (int 0)
minx (float (aget data 0))
maxx (float (aget data 0))
miny (float (aget data 1))
maxy (float (aget data 1))
minz (float (aget data 2))
maxz (float (aget data 2))]
(if (< i n)
(let [x (float (aget data (unchecked-add i 0)))
y (float (aget data (unchecked-add i 1)))
z (float (aget data (unchecked-add i 2)))]
(if (and (Float/isFinite x)
(Float/isFinite y)
(Float/isFinite z))
(recur (unchecked-add-int i (int 4))
(min minx x)
(max maxx x)
(min miny y)
(max maxy y)
(min minz z)
(max maxz z))
(recur (unchecked-add-int i (int 4))
minx
maxx
miny
maxy
minz
maxz
))
)
[minx maxx miny maxy minz maxz]))))
这就是Java代码的样子:
public class BBox {
public static float[] computeBBox(float[] data) {
long n = data.length;
float[] result = new float[6];
float minx = data[0];
float maxx = data[0];
float miny = data[1];
float maxy = data[1];
float minz = data[2];
float maxz = data[2];
for (int i = 0; i < n; i += 4) {
float x = data[i + 0];
float y = data[i + 1];
float z = data[i + 2];
if (java.lang.Float.isFinite(x) &&
java.lang.Float.isFinite(y) &&
java.lang.Float.isFinite(z)) {
minx = x < minx? x : minx;
maxx = x > maxx? x : maxx;
miny = y < miny? y : miny;
maxy = y > maxy? y : maxy;
minz = z < minz? z : minz;
maxz = z > maxz? z : maxz;
}
}
result[0] = minx;
result[1] = maxx;
result[2] = miny;
result[3] = maxy;
result[4] = minz;
result[5] = maxz;
return result;
}
};
我的问题是:
我可以对Clojure代码进行哪些更改,使其运行速度与Java代码一样快?如果您测试了您的代码并测量了速度,那么就可以获得额外的分数。
如果你想复制这个实验
published on my Github repository here
。