• Post Reply Bookmark Topic Watch Topic
  • New Topic

Once through or twice through?

 
Nick George
Ranch Hand
Posts: 815
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
So in my game, every cycle I go through my list of Things, and advance them all. Then, I go through it again and draw them all. It occured to me that this might be a cause of slowitude. As it would take rather a lot of work to change it to a once through thing where I advance and draw, I was hoping a sage could tell me if it's worth the reorganization.

Thanks,
Nick
 
Ernest Friedman-Hill
author and iconoclast
Sheriff
Posts: 24213
35
Chrome Eclipse IDE Mac OS X
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Are you having performance problems now? If not, don't worry about it. Loop overhead is quite small if the contents of the loop is at all nontrivial.
 
Jim Yingst
Wanderer
Sheriff
Posts: 18671
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hmmm, it's possible that even if the loop overhead is trivial (which it usually is), there might be significant time being spent retrieving each object's data from the heap. If that's the case, it could well be advantageous to retrieve each object once rather than twice. However I'd want to use a profiler first to determine where the performance issues (if any) really are.

[Nick]: As it would take rather a lot of work to change it to a once through thing where I advance and draw,

Regardless of performance issues, this line makes me think it might be worthwhile for you to spend a bit of time refactoring the code for greater clarity and simplicity. Maybe there's some good reason this needs to be more complex, but offhand I'd think that you should be looking at something like this:

and thinking about changing it to this:

There might be performance benefits from merging those two methods into one - e.g. if the position is stored in local variables x and y, it might be worthwhile to make sure the draw code uses the same x and y that the update code just set. But I'm hoping the JVM will optimize this stuff for you anyway. Can't really know without trying it, I think. After you've made some measurements of current performance and seen that there's a problem in this area...
 
Nick George
Ranch Hand
Posts: 815
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Ernest Friedman-Hill:
Are you having performance problems now? If not, don't worry about it. Loop overhead is quite small if the contents of the loop is at all nontrivial.


I'm always having performance problems- I can run about 500 of my little fellas at once without major slowdowns, but I'm always looking for ways to get more.

Someday I'll figure out how to work a profiler. Right now my profiler is 1000 fellas: which can do it better.
 
Jim Yingst
Wanderer
Sheriff
Posts: 18671
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Well, the "1000 fellas" can confirm for you that the performance isn't s good as you'd like. But the next question, what parts of your code are currently the bottleneck? Where should you focus your efforts to speed things up?

Most popular IDEs have a graphical profiler either built-in or available as a plugin. I really think it would be worth your while to spend a little time learning to use one. Good luck...
 
Reid M. Pinchback
Ranch Hand
Posts: 775
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The free version of JProbe would be good for figuring out if you want to make this change. The process is pretty easy:

- download and install the software
- create 2 unit tests to exercise your two variants
- tell JProbe to monitor what goes on and run the tests

You get a nice graphical tree structure to browse through to figure out where the time is going. You might need to control for classloading, GC, and hotspot activity, depending on what your code is doing.
 
Ilja Preuss
author
Sheriff
Posts: 14112
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Jim Yingst:
There might be performance benefits from merging those two methods into one - e.g. if the position is stored in local variables x and y, it might be worthwhile to make sure the draw code uses the same x and y that the update code just set.


Or it might severly hamper performance, due to increased number of cache misses. See the bottom of http://www.refactoring.com/catalog/splitLoop.html
 
Nick George
Ranch Hand
Posts: 815
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Intriguing
 
Nick George
Ranch Hand
Posts: 815
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
$500 for a program that took me 15 seconds to download? That's the stupidest thing I've ever heard in my life!

Oh, Bittorrent! Of all the times to have come up with zero results!
 
Jim Yingst
Wanderer
Sheriff
Posts: 18671
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
[Ilja]: Or it might severly hamper performance

Yep. This one can go either way, depending on the sizes of the arrays, and how the cache is managed. Splitting the loops can optimize access to the different arrays (if there are different arrays), while joining the loops can optimize access to the objects referenced by a single array (if it's an array of objects, not primitives). If you've got both effects going on, ut's hard to predict which will dominate. Which goes back to the importance of being able to measure the performance before & after any given optimization attempt, under conditions as close to "reality" as possible.

[Nick]: $500 for a program that took me 15 seconds to download?

If you're talking about JProbe, note that there's a trial version and a freeware version - not the same thing.
[ January 16, 2006: Message edited by: Jim Yingst ]
 
Nick George
Ranch Hand
Posts: 815
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
JProfiler- I have the trial version, and it seems to have everything (for the next ten days). Of course, I know nothing about the matter.
[ January 16, 2006: Message edited by: Nick George ]
 
Nick George
Ranch Hand
Posts: 815
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Which brings me to my next point: it seems that 50% of my computing time is taken up by collision detection, of which roughly 5% is actual collision detection, and the other 45% is every cycle, computing the distance between every two objects to see if I need to test for collision. That's n! Math.sqrts / cycle. Bet it would be quicker to just test if all of the x, y, and z axis are sufficiently close.
[ January 16, 2006: Message edited by: Nick George ]
 
Jim Yingst
Wanderer
Sheriff
Posts: 18671
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Well, yeah. Have you tried checking the bounding rectangles first, and only checking the more precise equation if the bounding rectangles overlap? And you don't really need Math.sqrt() either - just square both sides of the equation. It's faster to compute a square than a square root.
 
Nick George
Ranch Hand
Posts: 815
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Not sure this will lead to any improvements, but something else interesting: My time between cycles clusters around multiples of 16- I get 16 ms, 32 ms, 48 ms, 64 ms, et cetera. The more fellas, the higher the multiple I cluster around. I spose I might be able to improve performance if I could get 38 ms cycles instead of jumping to 48, but moreso I'm curious why that is.

The new method of checking distances caused a marked improvement.

Of course, a thousand thanks to all who are helping me in this thread, I've found it most interesting.
 
Jim Yingst
Wanderer
Sheriff
Posts: 18671
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Quick turnaround there. As for the times - is it possible that's the resolution of your system clock? Do you observe any time differences which are not multiples of 16 ms? Or if you're using multiple threads on a system with timeslicing, maybe the thread scheduler uses timeslices of 16 ms? (I have no idea what is typical for timeslices; just a shot in the dark here.)
[ January 16, 2006: Message edited by: Jim Yingst ]
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!