bkr879
bkr879

Reputation: 2105

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

So far, in a program that I am writing, I have been using arrays to store data about line segments. For the sake of the question, let's assume these arrays only contain integers that define start (x1, y1) and end (x2, y2) coordinates.

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

In my program, I need to continuously perform operations on the data contained in multiple such arrays using for loops.

In the course of writing the program, I have, numerous times, realized that I need more data about those segments. As a result, I added elements to the array, which grew larger, for instance:

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

This has become hard to manage, since I need to remember the position of each integer data to perform operations on it and it is very tedious to implement changes to the array, such as swapping the position of two elements, since I need to update the index of the elements in every part of the program that performs operations on them.

This has led me to the probably obvious idea to create a lineData class which contains the integers as its fields:

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

This looks like a good solution.

My concern, though, is that accessing and changing the fields of the lineData class will be slower than accessing and changing the elements in the array. The reason behind my concern is the belief that Arrays exist for a reason.

Another argument for using a lineList class is the need to store data about the line segments that are not integers, but Strings, Booleans and other custom objects.

However, please disregard that argument. I would like to compare an integer array with a class containing solely integer fields.

Summing up, my questions are:

Which one is faster: an array of x integers or an object containing x integer fields? How did you solve the described issue when you faced it in the past? If using an object with fields is slower than using an array, did you still decide to use an object with fields? Why?

Please take into account that there is a very high number of those arrays, so changing the arrays to objects with fields would create a very high number of instantiated objects that are looped over - maybe this has an effect on performance?

Thanks a lot in advance for your help!

Upvotes: 2

Views: 129

Answers (4)

cнŝdk
cнŝdk

Reputation: 32145

Using a LineData class to store your objetcs is much suitable, readable and surely faster than saving all the data successively in the same Array.

Because in that case for each line details you whould have to iterate the Array twice, first to reach the beginning of each line details and the second to loop throught those details which is very expensive and unwanted.

And for structure performance, using a Java Collections(List, Set and Map) to store those lines is better than using an Array, and to decide which one to use we need to know the difference between them and when to use each one of them:

  1. If you need to access elements frequently by using index, than List is a way to go. Its implementation e.g. ArrayList provides faster access if you know index.
  2. If you want to store elements and want them to maintain an order on which they are inserted into collection then go for List again, as List is an ordered collection and maintain insertion order.
  3. If you want to create collection of unique elements and don't want any duplicate than choose any Set implementation e.g. HashSet, LinkedHashSet or TreeSet. All Set implementation follow there general contract e.g. uniqueness but also add addition feature e.g. TreeSet is a SortedSet and elements stored on TreeSet can be sorted by using Comparator or Comparable in Java. LinkedHashSet also maintains insertion order.
  4. If you store data in form of key and value than Map is the way to go. You can choose from Hashtable, HashMap, TreeMap based upon your subsequent need. In order to choose between first two see difference between HashSet and HashMap in Java.

And I think in your case you just need to use a List of LineData objects (List<LineData>) to get a faster access to its elements:

Upvotes: 1

T.Gounelle
T.Gounelle

Reputation: 6033

First, I would say that if you handle only integers and you strive for performances, then you should certainly use int[] instead of Integer[]:

  • int[] is one single object that contains an array of native integers (4 bytes)
  • Integer[] is an array of Integer class, which means as many objects as the length of the array when all are instantiated.

Now on your question. Frankly, on your design and independently of performance issues, you should go for the LineData class. I don't see any good reason to implement a pseudo object in an array. Conceptually, it does not make sense to store things of different nature like slope, color, x, y,... in the same array. An array (even native) is a kind of collection, and then should contain values that are of the same nature.

On the performance, I would say the compiler can easily optimise getter and setter on an object.

Upvotes: 2

willeM_ Van Onsem
willeM_ Van Onsem

Reputation: 476537

Arrays exist to store a number of instance where the number is unknown, or where you will have to iterate over the instance and perform the same operation on them.

As a result it is better that an array contains the same (semantical) type of objects. This was in this case not true, you store a line width after a coordinate. Although technically there is no problem, it will be hard to maintain.

So from a development point of view, it is better to create a class that stores segments, and then store different line segments in an array.

So what you probably need is a LineData[] array. Where in each element you store the data of one line.

From a performance point of view, there is not much difference.

  • Access a field through a method: in that case you first call the method create overhead (call stack frame) as well as a null check, accessing the field itself is however fast, because Java knows the position of the field in advance.
  • Access a public field: is in general not considered a good idea. The advantage is that you only need to perfrom a null check on the object.
  • Accessing a array element. In that case two checks are done: a null-check on the array and an index check (this index check can be done in one operation if optimized (and on a machine with a reasonable instruction set).

However if you are not sure on the number of line segments in advance, you better use an List<LineData> instance, thus a LinkedList or an ArrayList.

Upvotes: 1

SQL.injection
SQL.injection

Reputation: 2647

Did you considered to use something like a list or a set?

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

Or maybe what do you need is a Map?

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

and the list of trick you can do goes on, are you sure you are using the right data structure?

Upvotes: 1

Related Questions