9

When writing something that creates many (1000s) of small objects often, should you try to minimize it for performance? Especially if you don't know what system it will be run on, from low to high end desktops or even mobile. For mobile, I heard that creating a lot of objects hinders the performance a good bit, though I don't know how true that is.

I have an example that shows this idea well. In a graphics program, say there is a method that is used for all drawing ideally called drawPixel(Point). There could be 1000s of Points created and it may be repeated often, like in a game where it could be called 60+ times a second. Alternatively, drawPixel(int x, int y) could be used to minimize the creation of many Point objects.

In an object-oriented design, I think using Point would be preferred. However, using primitive types may increase performance. The performance gain may be negligible in most cases, but I'm unsure about things like mobile or older machines. What is the performance gain from doing something like this and is it something that should be taken into consideration?

  • I'm having a tough time finding references to back this up, but in general in Java 8 just don't worry about it. Don't do obviously stupid things, but if you aren't deliberately wasteful the system should perform just fine. Sun/Oracle have had around 20 years to tune the GC and memory management and they have gotten really good at it. – user22815 Sep 14 '16 at 3:00
  • @Snowman I have heard that newer versions of Java do better with memory management, but the problem I see is that there is no guarantee the user isn't using an older version. That's part of what created this concern of mine. – Stripies Sep 14 '16 at 3:47
  • 1
    First do some performance measurement. If you have some troubles then think how to optimize. But please don't sacrify code maintainability too early because you think you could have some performance troubles. – Spotted Sep 14 '16 at 5:26
  • 2
    @Stripies Performance of short-lived Java objects already answered in Should we avoid object creation in Java?. However if you ever have to handle hundreds of millions of such objects per second then only at that point reconsider this issue. – rwong Sep 14 '16 at 5:50
  • 1
    If you're worried about older versions of Java, check for that when you install. A JVM old enough to cause a problem with memory management, also has lots of well known security problems as well, so prompting users to update is doing them a favor. System.getProperty("java.version") (or "java.vm.version") is a starting point. – Jerry Coffin Sep 14 '16 at 14:31
17

In general, no, you shouldn't avoid creating objects for fear of performance loss. There are several reasons for this.

  1. Using objects is kind of the point of using Java. Avoiding them preemptively is a sign that the decision to use Java might not have been the right one to begin with.
  2. Performance issues are notoriously hard to predict. Never assume that something is a bottleneck. Always measure. Performance engineering is almost always a matter of making small changes in exactly the right place. You cannot predict the right place without measuring any more than you can predict a medication's effect without an experiment.
  3. The cost of object creation is greatly overestimated. In a modern JVM it amounts basically to incrementing a pointer (and with generational garbage collectors, the cost of managing it is also trivial). There are a lot of texts on the internet that advise you to avoid objects, to use object pooling etc. This advise was sometimes right in the 1990s; today it is mostly obsolete. You are very unlikely to gain enough performance to justify the added development cost and complexity introduced by avoiding Objects or managing them yourself.

That said, there are places where making something into an object doesn't make sense to begin with. Passing two coordinates to a drawing routine might be such a case: the coordinate pair has no independent existence, it has no identity, it is used only once and then immediately discarded, etc.

If this is the case, then sure, go ahead and pass two ints rather than wrap them into an object. The point of OOP is not that everything must be an object. The point is that objects make development easier in places where they are the natural solution to a data representation problem. Don't avoid objects where they make sense - don't introduce them where they don't.

2

When contemplating impacts on performance before you've written code you should assume you don't know what you're doing.

There is a very small space overhead for objects in java versus primitives. The tinier your objects are, the larger the percentage of overhead will be. However, I learned long ago that things that double n are nothing compared to things that multiply n by n.

So while yes you could finagle some system that had half the size impact or even a fourth please ask yourself why you really care. Complicated solutions to this problem are not going to be well received. Particularly because diving into such code will be confusing. Confused programmers write bad code. They write n times n code that should be n log n code. And they take longer to do it.

Now if you can save me space with some trick that fits in a nice box that I don't have to look inside most of the time we can talk. If it's a box I can swap out for another box when that box would work better I may even pay for it.

2

In the performance tuning I've done (example) it is very easy for memory management to be a major culprit. I don't care how madly they've tuned the new operator and the garbage collector, the fastest computation is no computation. So if I find the memory manager takes a good percent of time, and I can't avoid making objects, then I find a way to re-use them, rather than constantly making new ones.

I only do this if I have to make objects. For graphics, usually I don't. IMHO, graphics should be drawn, not built. Sure, you could say that a picture consists of points, lines that connect them, polygons, text, and so on. That doesn't mean you have no alternative to making objects out of them before you draw them. I just draw them.

There's a Paint method. I override that, draw everything to a bitmap, and then block transfer it to the screen. It looks instantaneous. For mouse input, there are methods to override, to detect clicking, dragging, whatever.

OOP is a good idea for certain reasons. Those reasons don't apply in all situations.

  • I agree, but I also agree with everyone else that testing is the only way to know for sure. Be sure you have specs doing it the simple/obvious way before optimizing it... but I agree that new can still be an issue. – Bill K Apr 3 '18 at 23:19
2

Go ahead and use small allocations. Modern memory managers, particularly the highly optimized Java object manager, are extremely efficient. Save major performance optimization for a working program.

It is extremely likely that the overall performance will be adequate. If you find that is not the case, then, and only then, profile the code's performance. In a long career of software development, I've learned that the bottlenecks are almost never where you expect.

I once had a team member spend several days making object member lookup 20x faster. Success! However, the best overall speedup in actual use was measured in hundredths of a percent. The change was immediately backed out, since the speedup required larger per member memory allocations.

1

It's simple: If you need 1000 small objects, then you create 1000 small objects and don't worry about it. If you need 100 small objects, then creating 1000 small objects is stupid - create the ones that you need and not more.

If you are worried about performance (and if you are not worried about performance as well) you should have any functionality written once in one place, which makes your whole code simpler and easier to understand. Then if you have a performance problem, then measuring may show you that there is one place where the performance problem happens, which makes things easier, and only one place where you need to change it. Or measuring shows that this one place doesn't cause any problems, so you're done.

Your Answer

By clicking "Post Your Answer", you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.