哪个更快:x 个整数数组或包含 x 个整数字段的对象?

Which one is faster: an array of x integers or an object containing x integer fields?

到目前为止,在我正在编写的程序中,我一直使用数组来存储有关线段的数据。为了这个问题,我们假设这些数组只包含定义开始 (x1, y1) 和结束 (x2, y2) 坐标的整数。

Integer[] lineData = {x1, y1, x2, y2};

在我的程序中,我需要使用for循环不断地对多个这样的数组中包含的数据进行操作。

在编写程序的过程中,我无数次意识到我需要有关这些段的更多数据。结果,我向数组添加了元素,数组变大了,例如:

Integer[] lineData = {x1, y1, x2, y2, slope, red, green, blue, width};

这变得很难管理,因为我需要记住每个整数数据的位置才能对其执行操作,并且实现对数组的更改非常繁琐,例如交换两个元素的位置,因为我需要在对元素执行操作的程序的每个部分中更新元素的索引。

这让我想到了创建一个 lineData class 的可能显而易见的想法,其中包含整数作为其字段:

public class LineData {

public int x1,y1,x2,y2,slope, red, green, blue, width;

LineData(int x1, int y1, int x2, int y2, int slope, int red, int green, int blue, int width){
    this.x1 = x1;
    this.y1 = y1;
    this.x2 = x2;
    this.y2 = y2;
    this.slope = slope;
    this.red = red;
    this.green = green;
    this.blue = blue;
    this.width = width;
}

public int getX1() {
    return x1;
}

public void setX1(int x1) {
    this.x1 = x1;
}

public int getY1() {
    return y1;
}

public void setY1(int y1) {
    this.y1 = y1;
}

public int getX2() {
    return x2;
}

public void setX2(int x2) {
    this.x2 = x2;
}

public int getY2() {
    return y2;
}

public void setY2(int y2) {
    this.y2 = y2;
}

public int getSlope() {
    return slope;
}

public void setSlope(int slope) {
    this.slope = slope;
}

public int getRed() {
    return red;
}

public void setRed(int red) {
    this.red = red;
}

public int getGreen() {
    return green;
}

public void setGreen(int green) {
    this.green = green;
}

public int getBlue() {
    return blue;
}

public void setBlue(int blue) {
    this.blue = blue;
}

public int getWidth() {
    return width;
}

public void setWidth(int width) {
    this.width = width;
}
}

这看起来是个不错的解决方案。

不过,我担心的是访问和更改 lineData class 的字段将比访问和更改数组中的元素慢。我担心的原因是相信数组的存在是有原因的。

使用 lineList class 的另一个论点是需要存储关于线段的数据,这些数据不是整数,而是字符串、布尔值和其他自定义对象。

但是,请忽略该参数。我想将整数数组与仅包含整数字段的 class 进行比较。

综上所述,我的问题是:

哪个更快:x 个整数数组还是包含 x 个整数字段的对象? 当您过去遇到所描述的问题时,您是如何解决的?如果使用带字段的对象比使用数组慢,您是否仍决定使用带字段的对象?为什么?

请注意这些数组的数量非常多,因此将数组更改为具有字段的对象会创建大量循环的实例化对象 - 也许这会影响性能?

非常感谢您的帮助!

您是否考虑过使用列表或集合之类的东西?

List<Interger> myList = new ArrayList<Integer>();

myList.add(5);

boolean foo = myList.contains(5); // true

foo = myList.contains(6); // false

int size = myList.size(); // 1 
foo = myList.isEMpty(); //false   

myList.remove(new Integer(5));
size.size() // 0
foo = myList.isEmpty(); // true

或者您需要的是地图?

Map myMap<String,Integer> = new HashMap<String, Integer>();

myMap.put("blue", 5);
myMap.put("red", 6);

int value = myMap.get("red"); // 6
int size = myMap.size(); //2
myMap.remove("red");
size = myMap.sie(); //2

你可以做的技巧列表还在继续,你确定你使用了正确的数据结构吗?

Arrays 用于存储 数量未知 的实例数量,或者您必须 迭代 对实例执行相同的操作

因此,数组最好包含相同(语义)类型 的对象。在这种情况下这是不正确的,您在坐标后存储线宽。虽然技术上没问题,但是维护起来会比较麻烦

所以从开发的角度来说,最好是创建一个class来存储线段,然后将不同的线段存储在一个数组中。

所以您可能需要的是一个 LineData[] 数组。在每个元素中存储一行数据的位置。

性能的角度来看,差别不大。

  • 通过方法访问字段:在这种情况下,您首先调用方法创建开销(调用堆栈框架)以及空检查,但是访问字段本身是快,因为Java提前知道字段的位置。
  • 访问public字段:一般来说这不是一个好主意。优点是你只需要对对象执行null检查。
  • 访问数组元素。在这种情况下,会进行两项检查:对数组进行 null 检查和 index 检查(如果优化(并且在具有合理指令集的机器上),则可以在一次操作中完成此索引检查) .

但是,如果您事先不确定线段的数量,您最好使用 List<LineData> 实例,因此 LinkedListArrayList

首先,我想说如果你只处理整数并且你努力性能,那么你当然应该使用int[] 而不是 Integer[]:

  • int[] 是一个包含原生整数数组(4 字节)的单个对象
  • Integer[]Integerclass的数组,意思是全部实例化时,对象的个数与数组的长度一样多。

现在回答你的问题。 坦率地说,就您的设计和性能问题而言,您应该选择 LineData class。我看不出有任何理由在数组中实现 对象。从概念上讲,将 slopecolorxy 等不同性质的东西存储在同一个数组中是没有意义的。数组(甚至原生)是一种集合,因此应该包含具有相同性质的值。

关于性能,我想说编译器可以很容易地优化对象上的 getter 和 setter。

使用 LineData class 来存储您的对象适合可读并且肯定比将所有数据连续保存在同一个数组中快

因为在那种情况下,对于每一行详细信息,您必须迭代数组两次,第一次到达每行详细信息的开头,第二次循环遍历这些详细信息,这 非常昂贵不需要的.

对于结构性能,使用 Java 集合(List、Set 和 Map)来存储这些行比使用数组要好,要决定使用哪一个,我们需要知道它们之间的区别它们以及何时使用它们中的每一个:

  1. 如果您需要通过索引频繁访问元素,那么 List 是一个不错的选择。它的实施例如如果您知道索引,ArrayList 提供更快的访问。
  2. 如果你想存储元素并希望它们保持插入集合的顺序,那么再次使用 List,因为 List 是一个有序集合并保持插入顺序。
  3. 如果您想创建唯一元素的集合并且不想要任何重复项,那么选择任何 Set 实现,例如HashSet、LinkedHashSet 或 TreeSet。所有 Set 实施都遵循一般合同,例如独特性,但也添加附加功能,例如TreeSet 是一个 SortedSet,存储在 TreeSet 上的元素可以使用 Java 中的 Comparator 或 Comparable 进行排序。 LinkedHashSet 也维护插入顺序。
  4. 如果您以键和值的形式存储数据,那么 Map 是最佳选择。您可以根据您的后续需要从 Hashtable、HashMap、TreeMap 中进行选择。为了在前两个之间进行选择,请参阅 Java.
  5. 中 HashSet 和 HashMap 之间的区别

而且我认为在你的情况下你只需要使用 List of LineData objects (List<LineData>) 来获得更快地访问其元素: