简体   繁体   English

Java中的高性能原始数组构建器

[英]High performance primitive array builder in Java

I currently use google-or tools to solve a max flow problem, so this has me create a few int[] arrays in java to pass into ortools. 我目前使用google-or工具来解决最大流量问题,因此这使我在Java中创建了一些int []数组以传递到ortools中。 Now ortools is very fast and not an issue here but I'm open to performance minded alternatives here. 现在,ortools速度非常快,在这里不是问题,但在这里我可以考虑性能。

The problem lies mostly in building the arrays which takes a majority of the time as well as GC when the results are returned from which I chalk up to probably JNI overhead and not much I can do about that. 问题主要在于构建数组和返回结果时要花费大量时间的GC,而从中我花了大概的JNI开销,而我对此无能为力。 The primitive arrays approach around the 5 - 7 million point mark and they are large enough to require them to be integers, short is not an option. 基本数组接近5-700万个点标记,它们足够大以至于要求它们是整数,而短选择是不可行的。 Do I have any options or tricks or does anyone have any insight into how to most efficiently build these? 我是否有任何选择或技巧,或者是否有人对如何最有效地构建这些技巧有任何见解? Memory is not really an issue here I have enough that and for the most part I am open to any solution for the absolute bleeding edge performance, even if it requires a different representation of my data but this still must be able to be plugged into Ortools (unless You have an idea to replace it) but I welcome any suggestions at all regarding how to get the fastest array building out of this. 在这里,内存并不是真正的问题,我已经足够了,并且在大多数情况下,我愿意接受任何解决方案以实现绝对的前沿性能,即使它需要对我的数据进行不同的表示,但仍然必须能够将其插入Ortools (除非您有替换它的想法),但我完全欢迎有关如何从中获得最快阵列构建的任何建议。 Mind you I don't know the length of the arrays ahead of time, I don't do updates, deletes, only appends. 请注意,我不知道数组的长度,我不执行更新,删除,仅追加操作。 I'm happy to provide anymore details. 我很乐意提供更多细节。 Thanks for any suggestions. 感谢您的任何建议。

Too long for a comment. 评论太久了。

If building the problem representation takes a lot of time when compared to solving, then you're doing something wrong. 如果与解决方案相比,构建问题表示形式需要花费大量时间,则您做错了什么。 I guess, you're using something like 我想,您正在使用类似

int[] appendTo(int[] array, int element) {
    int[] result = Arrays.copyOf(array, array.length + 1);
    result[result.length - 1] = element;
    return result;
}

which has a quadratic complexity. 具有二次复杂度。 The solution is similar to what ArrayList does: Grow by some fixed factor and ignore trailing array elements. 该解决方案类似于ArrayList所做的事情:按某个固定因子增长,并忽略尾随的数组元素。 This mayn't be what you need at the end, but shrinking all arrays once (just before passing them to the library) is cheap. 最终可能并不需要这,但是将所有数组缩小一次(就在将它们传递到库之前)很便宜。

You could use a class like 您可以使用类似的类

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;
   }
}

or misuse the last element of an int[] for tracking the logical length (slightly more efficient, but very hacky). 或滥用int[]的最后一个元素来跟踪逻辑length (效率稍高,但很乱)。

There are various trade-offs, eg, you could reduce your growth factor to 1.5 by using length + (length >> 1) instead of 2 * length , start with shorter or longer arrays, or even with an empty array (like ArrayList does; then you'd need to adapt the growth factor as well). 需要进行各种折衷,例如,您可以通过使用length + (length >> 1)而不是2 * length来将增长因子降低到1.5,从较短或较长的数组开始,甚至从一个空数组开始(如ArrayList一样) ;那么您还需要调整增长因子)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM