Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用可编程的维数在java中实现快速多维数组?_Java_Arrays_Multidimensional Array - Fatal编程技术网

如何使用可编程的维数在java中实现快速多维数组?

如何使用可编程的维数在java中实现快速多维数组?,java,arrays,multidimensional-array,Java,Arrays,Multidimensional Array,默认的Java多维数组具有固定的维数,并且是复杂的初始化数组 但很少有自定义实现的尝试会导致运行速度降低数百倍 为什么? 下面的代码将两个自定义类Array1和Array2与内置数组进行比较。这两种自定义实现都需要比构建它多上百个时间 我已将整个代码发布到github上,因为我被告知: 我试图避免装箱、递归和其他潜在的减速 我还包括NDArray类Vectorz库的基准测试 同样的操作我也重复了三次 我发现速度是不可预测的 Allocating all arrays... Done. Writi

默认的Java多维数组具有固定的维数,并且是复杂的初始化数组

但很少有自定义实现的尝试会导致运行速度降低数百倍

为什么?

下面的代码将两个自定义类
Array1
Array2
与内置数组进行比较。这两种自定义实现都需要比构建它多上百个时间

我已将整个代码发布到github上,因为我被告知:

我试图避免装箱、递归和其他潜在的减速

我还包括
NDArray
Vectorz
库的基准测试

同样的操作我也重复了三次

我发现速度是不可预测的

Allocating all arrays...
Done.
Writing array1 (nested Object[])
Attempt: 0
Attempt 0 done. 60000000 elements in 2.540285659 seconds
Attempt: 1
Attempt 1 done. 60000000 elements in 9.411849662 seconds
Attempt: 2
Attempt 2 done. 60000000 elements in 5.808331906 seconds
Writing array2 (mapped plain Double[])
Attempt: 0
Attempt 0 done. 60000000 elements in 16.246523827 seconds
Attempt: 1
Attempt 1 done. 60000000 elements in 8.317891235 seconds
Attempt: 2
Attempt 2 done. 60000000 elements in 23.501270648 seconds
Writing array3 (conventional)
Attempt: 0
Attempt 0 done. 60000000 elements in 5.914992997 seconds
Attempt: 1
Attempt 1 done. 60000000 elements in 1.120277519 seconds
Attempt: 2
Attempt 2 done. 60000000 elements in 13.563776366 seconds
Writing array3 (NDArray of Vectorz)
Attempt: 0
Attempt 0 done. 60000000 elements in 1.461343338 seconds
Attempt: 1
Attempt 1 done. 60000000 elements in 0.943231111 seconds
Attempt: 2
Attempt 2 done. 60000000 elements in 1.384088957 seconds
Reading array1 (nested Object[])
Attempt: 0
Attempt 0 done. 60000000 elements in 0.271591626 seconds
Attempt: 1
Attempt 1 done. 60000000 elements in 0.238402884 seconds
Attempt: 2
Attempt 2 done. 60000000 elements in 0.242798686 seconds
Reading array2 (mapped plain Double[])
Attempt: 0
Attempt 0 done. 60000000 elements in 0.192451361 seconds
Attempt: 1
Attempt 1 done. 60000000 elements in 0.17005682 seconds
Attempt: 2
Attempt 2 done. 60000000 elements in 0.17020843 seconds
Reading array3 (conventional)
Attempt: 0
Attempt 0 done. 60000000 elements in 0.221501481 seconds
Attempt: 1
Attempt 1 done. 60000000 elements in 0.205166342 seconds
Attempt: 2
Attempt 2 done. 60000000 elements in 0.20135264 seconds
Reading array4 (NDArray of Vectorz)
Attempt: 0
Attempt 0 done. 60000000 elements in 1.020388133 seconds
Attempt: 1
Attempt 1 done. 60000000 elements in 0.950194307 seconds
Attempt: 2
Attempt 2 done. 60000000 elements in 0.977558831 seconds
Total application time is 97.40557648 seconds

您的实现比实例化一个简单的双精度多维数组要慢得多,因为

1) 使用Object=>将Object转换为double,程序将Object转换为double。你需要拆箱、装箱和铸造。这简直是浪费时间

2) 您使用的递归方法比迭代方法慢(这里不需要迭代方法)

注意:我不知道您将如何处理这些数组,但我非常确定有很多解决方案可以避免实例化大量数据,从而导致java堆空间内存。。。
这是对内存的浪费。

快速多维数组的底层实现应该是单个线性数组。如果您有一个二维尺寸数组
X
Y
,则从元素
[i][j]
读取的值将转换为位置
[i*X+j]
的读取值。这可以推广到更高的维度。内存块的cpu缓存意味着,如果对数组的基本元素进行迭代,则这些元素将以块的形式被提取到处理器缓存中,这样,对它们进行迭代可以避免到主内存的旅行。这正是Java多维数组的含义;它只是一个围绕单个线性内存板的方便包装器,而不是数组的数组

您没有考虑GC。运行程序时,我看到完整的GC为14秒。当没有GC时,Array2的运行速度与本机阵列一样快。使用以下标志运行:

-Xmx16g-verbose:gc-XX:+PrintGCDetails-XX:+PrintGCTimeStamps

使用这些标志运行程序会显示大量GC。请参阅此版本:


你的问题到底是什么?为什么不创建一个平面数组,并通过编程将元素映射到其中和之外?@hexafrance这是
Array2
类的一个想法,请看。@Bohemian为什么我的两个版本都写得这么慢?你能在循环中运行整个过程十次,并且只计算上一次迭代的测量值吗?也许JIT编译器会在一段时间后启动。我已经实现了您在
Array2
中所说的。由于某些原因,它的工作速度较慢。您没有发布代码,因此没有人可以给您答案。将其作为GitHub上的要点或pastebin或其他网站上的代码片段发布以共享代码。您已更改了问题,因此我已更改了答案。如何禁用GC?不用担心,我只需要时间