Java中的高性能原语数组生成器

Java中的高性能原语数组生成器,java,arrays,performance,jvm,or-tools,Java,Arrays,Performance,Jvm,Or Tools,我目前使用google或工具来解决最大流问题,因此这让我在java中创建了一些int[]数组来传递到ortools中。现在ortools速度非常快,在这里不是问题,但我在这里愿意接受注重性能的替代方案 问题主要在于构建数组,这需要花费大部分时间以及返回结果时的GC,我认为这可能是JNI开销,对此我无能为力。基本数组接近500-700万点,它们足够大,要求它们是整数,short不是一个选项。我是否有任何选择或技巧,或者是否有人对如何最有效地构建它们有任何见解?内存并不是一个真正的问题,我有足够的内

我目前使用google或工具来解决最大流问题,因此这让我在java中创建了一些int[]数组来传递到ortools中。现在ortools速度非常快,在这里不是问题,但我在这里愿意接受注重性能的替代方案

问题主要在于构建数组,这需要花费大部分时间以及返回结果时的GC,我认为这可能是JNI开销,对此我无能为力。基本数组接近500-700万点,它们足够大,要求它们是整数,short不是一个选项。我是否有任何选择或技巧,或者是否有人对如何最有效地构建它们有任何见解?内存并不是一个真正的问题,我有足够的内存,并且在大多数情况下,我愿意接受任何绝对前沿性能的解决方案,即使它需要不同的数据表示形式,但这仍然必须能够插入到Ortools中(除非
您有一个替换它的想法),但我欢迎您提出任何关于如何从中获得最快阵列构建的建议。请注意,我事先不知道数组的长度,我不做更新、删除,只做附加操作。我很乐意提供更多细节。谢谢你的建议

评论太长

如果与解决问题相比,构建问题表征需要花费大量时间,那么你就做错了。我猜你用的是

int[] appendTo(int[] array, int element) {
    int[] result = Arrays.copyOf(array, array.length + 1);
    result[result.length - 1] = element;
    return result;
}
它具有二次复杂性。该解决方案类似于
ArrayList
所做的:按某个固定因子增长并忽略尾部数组元素。这可能不是您最后需要的,但是将所有数组收缩一次(就在将它们传递到库之前)是很便宜的

你可以使用像这样的类

class MyIntArray {
   private int length;
   private int[] data = new data[4];

   // This does the final shrinking.
   public int[] toArray() {
       return Arrays.copyOf(array, length);
   }

   public MyIntArray append(int element) {
       if (array.length == length) {
           array = Arrays.copyOf(array, 2 * length);
       }
       array[length++] = element;
   }
}
或者滥用
int[]
的最后一个元素来跟踪逻辑
长度(效率稍高,但非常粗糙)


有各种权衡,例如,您可以使用
length+(length>>1)
而不是
2*length
,将增长因子降低到1.5,从较短或较长的数组开始,甚至使用空数组(如
ArrayList
这样做;然后您还需要调整增长因子)。

太长,无法发表评论

如果与解决问题相比,构建问题表征需要花费大量时间,那么你就做错了。我猜你用的是

int[] appendTo(int[] array, int element) {
    int[] result = Arrays.copyOf(array, array.length + 1);
    result[result.length - 1] = element;
    return result;
}
它具有二次复杂性。该解决方案类似于
ArrayList
所做的:按某个固定因子增长并忽略尾部数组元素。这可能不是您最后需要的,但是将所有数组收缩一次(就在将它们传递到库之前)是很便宜的

你可以使用像这样的类

class MyIntArray {
   private int length;
   private int[] data = new data[4];

   // This does the final shrinking.
   public int[] toArray() {
       return Arrays.copyOf(array, length);
   }

   public MyIntArray append(int element) {
       if (array.length == length) {
           array = Arrays.copyOf(array, 2 * length);
       }
       array[length++] = element;
   }
}
或者滥用
int[]
的最后一个元素来跟踪逻辑
长度(效率稍高,但非常粗糙)


有各种权衡,例如,您可以使用
length+(length>>1)
而不是
2*length
,将增长因子降低到1.5,从较短或较长的数组开始,甚至使用空数组(如
ArrayList
,然后您还需要调整增长因子)。

问题尚不清楚。如果您有性能问题,请分享代码和用于衡量性能的方法。由于您提到JNI,最好使用直接缓冲区,例如
IntBuffer b=ByteBuffer.allocateDirect(size*Integer.BYTES).order(ByteOrder.nativeOrder()).asIntBuffer(),这要求JNI代码能够处理它们。如果性能问题与JNI无关,那么它可能是一个逻辑错误,比如,或者没有什么需要改进的。问题还不清楚。如果您有性能问题,请分享代码和用于衡量性能的方法。由于您提到JNI,最好使用直接缓冲区,例如
IntBuffer b=ByteBuffer.allocateDirect(size*Integer.BYTES).order(ByteOrder.nativeOrder()).asIntBuffer(),这要求JNI代码能够处理它们。如果性能问题与JNI无关,那么它要么是一个逻辑错误,比如,要么没有什么可改进的。