1

I have a Rectangle class and its constructor sets every variable (x, y, width, height) to a specific value. After a Rectangle is being created, if I want to change all of its values. To do that, is it more efficient to have a function like rect.set(newX, newY, newWidth, newHeight); or to call the constructor r1 = new Rectangle(newX, newY, newWidth, newHeight); all over again ? (Since I won't be referencing the older Rectangle anymore)

public Rectangle (int x, int y, int width, int height) {
    this.x = x;
    this.y = y;
    this.width = width;
    this.height = height;
}

public void set (int x, int y, int width, int height) {
    this.x = x;
    this.y = y;
    this.width = width;
    this.height = height;
}

I would imagine that creating a new rectangle will create garbage, so it should be worse. Is this true ? or does java somehow optimize this ?

dimitris93
  • 4,155
  • 11
  • 50
  • 86
  • Um....you can't call `set` (as defined above) until you have a `Rectangle` instance. And you can't get a `Rectangle` instance (as defined above) without calling the constructor that sets the properties. – T.J. Crowder Aug 24 '15 at 23:33
  • @T.J.Crowder I am aware of that, my question is about `changing a rectangle's value`, after it is being initialized. I am not a beginner in programming. – dimitris93 Aug 24 '15 at 23:34
  • Well, your question is really unclear. What is it you actually want to compare? (And how is this not incredible micro-optimization?) If you want to compare two things, Step 1 is **defining**, clearly and unambigously, what those two things are. – T.J. Crowder Aug 24 '15 at 23:35
  • @T.J.Crowder I thought it is was pretty clear. If I have a `rect1` instance and I want to change its value, do I call `rect1.set(newX, newY, newWidth, newHeight);` or `rect1 = new Rectangle(newX, newY, newWidth, newHeight);`. What is more efficient and why ? – dimitris93 Aug 24 '15 at 23:37
  • *"If I have a rect1 instance and I want to change its value"* There's your answer: Call `set`. Creating a new `Rectangle` **creates a new `Rectangle`**, it doesn't "change its value". Again: This is unclear. Creating a new instance doesn't change an existing instance. Just post two bits of code showing what you want to compare, to make things clear. – T.J. Crowder Aug 24 '15 at 23:39
  • @T.J.Crowder I had a typo, I meant changing its `values` not `value`, I was referring to the `x,y,width,height` properties of the rectangle. – dimitris93 Aug 24 '15 at 23:41
  • But creating a **new** rectangle **doesn't** changes its values. It creates a new rectangle, without in any way affecting the values of the old rectangle. – T.J. Crowder Aug 24 '15 at 23:42
  • 1
    @T.J.Crowder I think you have to read his question more like this: Is the performance gap between allocation of a new rect that significant, that one might favour mutable rects over immutable ones. Assuming the old rect isn't referenced any longer. – Sebastian S Aug 24 '15 at 23:47
  • @SebastianS: Well, that's one possibility. It would be trivial to update the question to clarify if it's what's actually meant. :-) So far the OP seems unwilling to do so. – T.J. Crowder Aug 24 '15 at 23:48
  • @T.J.Crowder This is indeed what I meant. – dimitris93 Aug 24 '15 at 23:49
  • 1
    @Shiro: Consider updating the question to make that clear. – T.J. Crowder Aug 24 '15 at 23:52
  • @T.J.Crowder I honestly don't know how to describe what I want more properly. The reason I chose `Rectangle` as an example makes the question self explanatory in my eyes. I would not be using `new` if I wanted to keep the older reference. I am just trying to change the values x,y,width,height, so one way to do it, is by simply creating a `new Rectangle` and another way is having a `set()` function. So, I am trying to figure out if it is worth it to be calling `set()`, because I have never seen it being used – dimitris93 Aug 25 '15 at 00:00
  • You never have `Rectangle r1 = new Rectangle(...); Rectangle r2 = new Rectangle(...);`?!?! – T.J. Crowder Aug 25 '15 at 00:07

7 Answers7

1

As a general rule, my preference would be to make as many objects in a Java application immutable as is practical. That way, you can avoid a range of issues, particularly around concurrency, that might otherwise make it harder to reason about the behaviour of your application.

This would mean avoiding adding setters and other methods that can mutate the value of your objects after construction.

This is especially true for objects that simply aggregate data, such as the Rectangle class you are describing.

There is more discussion about immutability here.

Community
  • 1
  • 1
clstrfsck
  • 14,715
  • 4
  • 44
  • 59
1

Personally, I prefer the Set. The base of object oriented programming is to think entity as a specific object. In your case, the rectangle is the object you instantiate with the "New Rectangle" call.

If you change its size, you must change the object with a "set" instead of creating another "Evil twin" of that rectangle.

That's my humble opinion.

Patophe
  • 21
  • 4
1

When you're dealing with millions of instances, these are probably stored in some kind of collection. And you will most likely use hashcode/equals based on x/y/width/height. If your objects are mutable, you might have problems identifying existing objects in your collections.

The best solution would probably be using value types but this isn't an option yet.

From a design point of view you will most likely avoid a lot of problems when using immutable objects, as the identity of your object depends on the properties you want to change.

Edit:

If however there is only one instance of an rectangle at a time, that changes frequently, you should keep one reference to a mutable object and change its values. See Aivean's answer, too.

Sebastian S
  • 4,420
  • 4
  • 34
  • 63
  • I think you got me wrong. I am using `new Rectangle()` a million times, however I re-write the same rectangle. So the other references go null and only 1 is non-null at a time. – dimitris93 Aug 25 '15 at 00:14
0

Depends on your design, and your motivation.
I tend to favour having immutable objects so I would have setters that return a new Rectangle, or have a static factory method to create a new rectangle.

Of course that is just my opinion, and can sometimes cause more code to be written, but because the object "can't be changed", the JVM should be able to reason better about the object, and maybe apply optimisations.

Gavin
  • 1,725
  • 21
  • 34
0

This is rather old question. What to do is highly dependent on your task.

Of course, creating object has some overhead comparing to mutating existent object, but in most cases it is negligible. Overall creating new objects is the preferable way from design point of view.

Hotspot JVM (desktop) is highly optimized for creating large amounts of short-lived objects.

Read more: https://softwareengineering.stackexchange.com/questions/149563/should-we-avoid-object-creation-in-java

However, on other platforms, such as Android, excessive object creation can lead to noticeable GC pauses, thus should be avoided, especially in game development.

UPD

From gathering scraps of information across the comments I can conclude:

  • You are writing game for Android
  • You have one logical Rectangle instance at each moment of time
  • You are modifying it large number of times (probably in a cycle within some method)

In these conditions the only reasonable approach will be to mutate single instance of Rectangle.

Rationale:

  • Avoid GC pause on Android
  • Encapsulate mutated Rectangle instance in method/class (It's perfectly ok to violate some design practices in performance-critical spots as long as these spots are encapsulated and you know what you are doing)
Community
  • 1
  • 1
Aivean
  • 10,692
  • 25
  • 39
  • Game development and android is what I am doing, and the object's rectangle's values are being changed in the scale of millions per second, at times. In this specific case (where I would have to use `excessive object creation` as you say, what do you think is best ? – dimitris93 Aug 24 '15 at 23:51
  • 1
    @Shiro well, in this case you should probably use [object pools](http://www.devahead.com/blog/2011/12/recycling-objects-in-android-with-an-object-pool-to-avoid-garbage-collection/). However, be careful about *premature optimization*. I'd suggest to write you logic first, measure performance and only after that optimize it. – Aivean Aug 24 '15 at 23:57
  • @Shiro Ok, actually, if you are doing millions of modifications of rectangles, probably this is part of your engine core. In this case it is essential to make it as fast as possible. I can't make suggestions without actually seeing your code, but must probably you would need to preallocate array of `Rectangle` and reuse it. – Aivean Aug 25 '15 at 00:03
0

That's right it depends on many things, but I think in general ( if we talk about optimizzation and not design ) the "set" solution will be more efficient and "platform independent" (Android).

Personally I always avoid the creation of a lot of objects I always try to reuse it as much as possible, especially on Android, trying to avoid bad thing like GC and bad memory usage.

But this is only my philosophy.

GGC
  • 102
  • 5
-1

Changing the object properties is the way to go! Once you start creating more than one rectangle, you will have multiple objects, and once instantiated, you can use them as much as you want, and that is the whole point of OOP programming! The other way is also efficient though, but personally I would use the one I just explained.

Happy coding, Rich

Ruchir Baronia
  • 7,406
  • 5
  • 48
  • 83