具有预定大小的数组的toArray

时间:2018-11-13 15:23:47

标签: java android arrays virtual-machine dalvik

在使用ar.toArray(new String[ar.size()]) Android Studio 3.2.1时警告有关预定大小的数组,并建议使用空数组

  

有两种样式可以将集合转换为数组:   预定大小的数组(例如c.toArray(new String [c.size()]))或使用   空数组(如c.toArray(new String [0])。在旧版Java中   建议使用预大小的数组,因为反射调用是   创建适当大小的数组所必需的速度非常慢。然而   自从OpenJDK 6的最新更新以来,此调用引起了人们的注意,   空数组版本的性能相同,有时甚至   比预大小版本更好。还通过了预尺寸   数组对于并发或同步集合是危险的,因为   在size和toArray调用之间可能发生数据争夺   如果集合是,则在数组末尾产生额外的null   在手术过程中同时缩小。该检查允许   遵循统一的样式:使用空数组(即   建议在现代Java中使用)或使用预定大小的数组(可能是   在较旧的Java版本或非基于HotSpot的JVM中更快。

是Android还是Java?

  

使用预定大小的数组(在较早的Java版本中可能更快   或非基于HotSpot的JVM)。

因为我认为Android不是HotSpot,其虚拟机是Dalvik,而现在是ART

3 个答案:

答案 0 :(得分:1)

好问题。

https://shipilev.net/blog/2016/arrays-wisdom-ancients/#_new_reflective_array

  

底线toArray(new T[0])似乎更快,更安全且符合合同规定   更清洁,因此现在应该是默认选择。未来虚拟机   优化可能会弥补toArray(new T[size])的性能差距,   使当前“被认为是最佳”用法与   实际上是最佳选择。 toArray API中的Further improvements   遵循与toArray(new T[0])相同的逻辑-集合本身   应该创建适当的存储。

答案 1 :(得分:0)

我不是Java历史学家,但是...

HotSpot实质上是由Oracle维护和分发的特定类型JVM的商标。它的名称来自即时编译器,该编译器可以检测到频繁执行的代码的“热点”并即时对其进行优化。

Android运行时也具有这种JIT编译器行为,并且可以在安装时将Java字节码提前编译为本机代码。

这使我认为ART与HotSpot属于同一类别(就此检查而言),因此您应该使用此调用的“空数组”版本。


如有疑问,请测量!

确定的最好方法是编写一个测试程序,该程序执行两种方法的版本并测量哪种方法运行得更快。


来源:

答案 2 :(得分:0)

它读取since late updates of OpenJDK 6,使用哪个运行时都无关紧要-因为在Dalvik上作为编译类运行的代码的语言级别可能是Java 6、7 8.只关系到项目使用哪种语言级别进行编译。例如:

compileOptions {
    sourceCompatibility JavaVersion.VERSION_1_8
    targetCompatibility JavaVersion.VERSION_1_8
}

设置JavaVersion.VERSION_1_6甚至可能会禁用检查投诉...在这些过时的设备上修复性能问题可能不值得付出努力-某些/大多数甚至都不会受到影响,因为只有“早期更新”行为与后续行为有所不同。