Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/13.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:制作初始ArrayList的本地副本的最快方法?_Java_Arrays_Arraylist - Fatal编程技术网

Java:制作初始ArrayList的本地副本的最快方法?

Java:制作初始ArrayList的本地副本的最快方法?,java,arrays,arraylist,Java,Arrays,Arraylist,我的代码要求我在每次调用函数时创建一个大的(301x301x19项)ArrayList,它有一些初始值(一些是0,一些是1,等等)。起始值总是相同的,每次调用函数时都需要将其加载到数组中,以便函数有自己的初始值副本来处理 最初,每次调用函数时,我都会重新计算数组,但结果证明速度慢得可笑;相反,我现在只计算初始数组一次,并且每次调用函数时都制作它的本地副本(这样我就可以在不更改初始数组值的情况下更改值) 但是,复制数组的速度仍然非常慢(仅复制此数组就花费了超过3/4的计算时间)。我尝试了以下方法:

我的代码要求我在每次调用函数时创建一个大的(301x301x19项)ArrayList,它有一些初始值(一些是0,一些是1,等等)。起始值总是相同的,每次调用函数时都需要将其加载到数组中,以便函数有自己的初始值副本来处理

最初,每次调用函数时,我都会重新计算数组,但结果证明速度慢得可笑;相反,我现在只计算初始数组一次,并且每次调用函数时都制作它的本地副本(这样我就可以在不更改初始数组值的情况下更改值)

但是,复制数组的速度仍然非常慢(仅复制此数组就花费了超过3/4的计算时间)。我尝试了以下方法:

// oldList is an ArrayList<Byte>
ArrayList<Byte> newList = new ArrayList<Byte>(oldList);

// oldList is an ArrayList<Byte>
ArrayList<Byte> newList = new ArrayList<Byte>();
newList.addAll(oldList);

// oldList is a Byte[]
ArrayList<Byte> newList = new ArrayList<Byte>(Arrays.asList(oldList));
//oldList是一个ArrayList
ArrayList newList=新ArrayList(旧列表);
//oldList是一个数组列表
ArrayList newList=新的ArrayList();
newList.addAll(oldList);
//oldList是一个字节[]
ArrayList newList=newarraylist(Arrays.asList(oldList));
所有这些方法对于我的应用来说都太慢了;有没有比这更快的技巧,或者我运气不好?

总之:

  • 旨在设计出复制如此多大型数据结构的需求(我知道这是一个难题)
  • 避免指针追逐,使用数组而不是ArrayList。如果对象包含其他对象,请尝试将其替换为基本体。这里的最终目的是将其简化为一个基元数组,例如字节数组
  • 压缩数据结构,使用数组和更小的类型;我们的目标是通过复制更少的实际字节获得相同的好处
  • 使用System.arrayCopy
  • 如果您仍然希望更快,那么将内存布局和责任从JVM中移开,直接使用sun.misc.Unsafe(也称为“剪式运行”)
  • 更改为更易于复制的数据结构,并使用System.arraycopy将以您在问题中概述的方法尽可能快地完成

    System.arraycopy作为本机调用实现。大多数JVM提供程序将准备一个本机版本,该版本使用本机指令来加速内存复制

    不幸的是,在JVM中复制大内存区域会产生意外的副作用,主要是在垃圾收集器周围

  • 在mem复制期间,JVM无法访问安全点,这会阻止STW GC启动
  • GC不启动会导致关注安全点的线程等待更长时间,从而在与此工作无关的线程上创建奇怪的暂停
  • 大数组可能不适合该选项卡(用于加速对象分配的线程本地缓冲区),这意味着对象分配在输入特殊情况代码时会减慢
  • 大型物体增加了GC循环期间过早使用的可能性,从而增加了更昂贵的老一代/完整GC的频率(与更便宜的年轻一代GC相反)

    • 注意:要看到上述影响,我们必须讨论非常高的分配率和丢弃率。大多数算法,做一些分配和复制在这里和那里不会看到这些问题;现代JVM甚至可以处理相当高的速率,这些问题直到超过阈值并且我们在磁极上旋转的板开始撞击地板时才会发生
  • 总之:

  • 旨在设计出复制如此多大型数据结构的需求(我知道这是一个难题)
  • 避免指针追逐,使用数组而不是ArrayList。如果对象包含其他对象,请尝试将其替换为基本体。这里的最终目的是将其简化为一个基元数组,例如字节数组
  • 压缩数据结构,使用数组和更小的类型;我们的目标是通过复制更少的实际字节获得相同的好处
  • 使用System.arrayCopy
  • 如果您仍然希望更快,那么将内存布局和责任从JVM中移开,直接使用sun.misc.Unsafe(也称为“剪式运行”)
  • 更改为更易于复制的数据结构,并使用System.arraycopy将以您在问题中概述的方法尽可能快地完成

    System.arraycopy作为本机调用实现。大多数JVM提供程序将准备一个本机版本,该版本使用本机指令来加速内存复制

    不幸的是,在JVM中复制大内存区域会产生意外的副作用,主要是在垃圾收集器周围

  • 在mem复制期间,JVM无法访问安全点,这会阻止STW GC启动
  • GC不启动会导致关注安全点的线程等待更长时间,从而在与此工作无关的线程上创建奇怪的暂停
  • 大数组可能不适合该选项卡(用于加速对象分配的线程本地缓冲区),这意味着对象分配在输入特殊情况代码时会减慢
  • 大型物体增加了GC循环期间过早使用的可能性,从而增加了更昂贵的老一代/完整GC的频率(与更便宜的年轻一代GC相反)

    • 注意:要看到上述影响,我们必须讨论非常高的分配率和丢弃率。大多数算法,做一些分配和复制在这里和那里不会看到这些问题;现代JVM甚至可以处理相当高的速率,这些问题直到超过阈值并且我们在磁极上旋转的板开始撞击地板时才会发生

  • 在内存中保留数组中的字节不是有效的计算。我想知道你为什么要使用数组/列表?如果您可能这样做,请使用流