Performance 在Clojure中提高点云边界框计算的性能
我正在计算Clojure中3d点云的边界框。点云表示为Java基本浮点数组,点云中的每个点都使用4个浮点存储,其中最后一个浮点未使用。像这样:Performance 在Clojure中提高点云边界框计算的性能,performance,clojure,geometry,clojure-java-interop,Performance,Clojure,Geometry,Clojure Java Interop,我正在计算Clojure中3d点云的边界框。点云表示为Java基本浮点数组,点云中的每个点都使用4个浮点存储,其中最后一个浮点未使用。像这样: [x0 y0 z0 u0 x1 y1 z1 u1 .... ] 点云的大小为19200,即阵列中的浮点数为4*19200 其中一些值可能不是有限的(要么是无限的,要么是NaN)。因此,任何包含非有限值的点都应该完全排除在计算之外。我已经在Java和Clojure中实现了这个计算,但是由于某些原因,Clojure版本仍然要慢4到5倍 这就是Clojur
[x0 y0 z0 u0 x1 y1 z1 u1 .... ]
点云的大小为19200,即阵列中的浮点数为4*19200
其中一些值可能不是有限的(要么是无限的,要么是NaN)。因此,任何包含非有限值的点都应该完全排除在计算之外。我已经在Java和Clojure中实现了这个计算,但是由于某些原因,Clojure版本仍然要慢4到5倍
这就是Clojure代码的样子:
(定义良好的计算bbox[^floats data]
(设[n(长度数据)]
(循环[i(int 0)
最小值(浮动(aget数据0))
maxx(浮动(aget数据0))
miny(浮动(aget数据1))
最大值(浮动(aget数据1))
minz(浮动(aget数据2))
maxz(浮点(aget数据2))]
(如果(
这就是Java代码的样子:
公共类BBox{
公共静态浮点[]计算框(浮点[]数据){
长n=数据长度;
float[]结果=新的float[6];
浮点最小值=数据[0];
float maxx=数据[0];
float miny=数据[1];
浮点最大值=数据[1];
float minz=数据[2];
float maxz=数据[2];
对于(int i=0;imaxx?x:maxx;
miny=ymaxy?y:maxy;
minz=zmaxz?z:maxz;
}
}
结果[0]=minx;
结果[1]=maxx;
结果[2]=miny;
结果[3]=最大值;
结果[4]=minz;
结果[5]=maxz;
返回结果;
}
};
我的问题是:我可以对Clojure代码进行哪些更改,使其运行速度与Java代码一样快?如果您测试了您的代码并测量了速度,那么您将获得额外的积分
如果你想重现这个实验,这里的罪魁祸首——正如我从你已经怀疑的代码中所看到的——是min
。它适用于各种类型,速度也不是很快
通过使用Apache的commons fast math,您可以获得10%以内的Java:
(defn primitive-compute-bbox-new [^floats data]
(let [n (alength data)]
(loop [i (int 0)
minx (aget data 0)
maxx (aget data 0)
miny (aget data 1)
maxy (aget data 1)
minz (aget data 2)
maxz (aget data 2)]
(if (< i n)
(let [x (aget data (unchecked-add i 0))
y (aget data (unchecked-add i 1))
z (aget data (unchecked-add i 2))]
(if (and (Float/isFinite x)
(Float/isFinite y)
(Float/isFinite z))
(recur (unchecked-add-int i 4)
(FastMath/min (float minx) x)
(FastMath/max (float maxx) x)
(FastMath/min (float miny) y)
(FastMath/max (float maxy) y)
(FastMath/min (float minz) z)
(FastMath/max (float maxz) z))
(recur (unchecked-add-int i 4)
minx
maxx
miny
maxy
minz
maxz)))
[minx maxx miny maxy minz maxz]))))
非常感谢您花时间回答这个问题。我将您的答案与此承诺合并:。但是,使用我添加的基准函数(runbenchmark),我没有发现任何显著的性能改进。但我不知道,我的基准测试在某种程度上可能存在缺陷。无论如何,谢谢。您是否多次运行基准测试功能?第一轮没有代表性。当我反复运行您的基准代码时,上面的版本与Java版本的差距在5-10%以内。我确实运行过几次,但它似乎稳定在Java版本“运行时间:20.761929毫秒”良好的计算bbox“运行时间:80.856727毫秒”原始计算bbox new“运行时间:99.636311毫秒”但是有很多原因可以解释为什么对你来说差异更小。。。比如JDK版本。
(defn primitive-compute-bbox-new [^floats data]
(let [n (alength data)]
(loop [i (int 0)
minx (aget data 0)
maxx (aget data 0)
miny (aget data 1)
maxy (aget data 1)
minz (aget data 2)
maxz (aget data 2)]
(if (< i n)
(let [x (aget data (unchecked-add i 0))
y (aget data (unchecked-add i 1))
z (aget data (unchecked-add i 2))]
(if (and (Float/isFinite x)
(Float/isFinite y)
(Float/isFinite z))
(recur (unchecked-add-int i 4)
(FastMath/min (float minx) x)
(FastMath/max (float maxx) x)
(FastMath/min (float miny) y)
(FastMath/max (float maxy) y)
(FastMath/min (float minz) z)
(FastMath/max (float maxz) z))
(recur (unchecked-add-int i 4)
minx
maxx
miny
maxy
minz
maxz)))
[minx maxx miny maxy minz maxz]))))
[org.apache.commons/commons-math3 "3.6.1"]