Problems with too many color objects

T

Tristan

Hi,

how can I reduce the color objects being created in my program ?
My program is an animation, where colors changes very often in an
endless loop. There are too many new Color(...) statements, so I got
problems with the performance. Any advice ?

Thank you.

Cu,

Tristan.
 
C

Chris Smith

Tristan said:
how can I reduce the color objects being created in my program ?
My program is an animation, where colors changes very often in an
endless loop. There are too many new Color(...) statements, so I got
problems with the performance. Any advice ?

Not being at all familiar with your application, few of us are likely to
be able to help very much. Here are a few things to check:

1. Can you cache instances of java.awt.Color?

2. Are you sure that you aren't holding onto the instances longer than
you really need to?

--
www.designacourse.com
The Easiest Way to Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 
T

Tristan

Hi,
Not being at all familiar with your application, few of us are likely to
be able to help very much. Here are a few things to check:

I'm sorry for the lack of information.
Here is a snippet of my procedure, that does a fade in for a text:

private void fadeColor(Color pOldColor, Color pNewColor) {

int oldRed = pOldColor.getRed();
int oldGreen = pOldColor.getGreen();
int oldBlue = pOldColor.getBlue();

int newRed = pNewColor.getRed();
int newGreen = pNewColor.getGreen();
int newBlue = pNewColor.getBlue();

while ((oldRed != newRed) || (oldGreen != newGreen) || (oldBlue != newBlue)) {

if (oldRed > newRed) {
oldRed--;
} else if (oldRed < newRed) {
oldRed++;
}

if (oldGreen > newGreen) {
oldGreen--;
} else if (oldGreen < newGreen) {
oldGreen++;
}

if (oldBlue > newBlue) {
oldBlue--;
} else if (oldBlue < newBlue) {
oldBlue++;
}

color = new Color(oldRed, oldGreen, oldBlue);

// repaint container
card.repaint();
try {
sleep(20);
} catch (InterruptedException ie) {};

}
}

The problem is that I have many threads that perform this procedure.
Could anyone help ?

Cu, Tristan.
 
M

Matt Humphrey

Tristan said:
Hi,

how can I reduce the color objects being created in my program ?
My program is an animation, where colors changes very often in an
endless loop. There are too many new Color(...) statements, so I got
problems with the performance. Any advice ?

Although I can guess that your performance problem is that your program
seems slow, I have to ask how do you know it's caused by too many new Color
statements? Have you profiled your program to determine where the
performance bottleneck really is?

That said, there are a couple of different places where you might get
problems with having too many colors. Although you seem to be suggesting
that you're creating a huge number of color objects, it's not strictly their
creation that's the problem. The real problem would be that they are all
being created and disposed at a furious and unnecessary pace. (Creating them
and not running out of memory is not a problem.) You should be able to
determine how many you're creating and disposing by simple use of a
profiler.

What I would be more concerned about is your choice of rendering algorithm
to begin with. Why does it need to create so many different colors on the
fly and continuously? Can you use a primitive (like a 32-bit number) instead
of a color object? More importantly, how does your animation relate to your
hardware? If your animation is defined as 24/32 bit RGB colors, but your
display has a limited palette (16 bit table) your underlying graphics
library will be going beserk mapping your colors into what's available. On
some systems (like X Windows) palette management in the underlying JVM /
Toolkit is very complicated but all come down to the same thing: how many
colors do you want to use and how many does your display allow.

What results did you get from your profiler?

Cheers,
Matt Humphrey (e-mail address removed) http://www.iviz.com/
 
J

John C. Bollinger

Tristan said:
Here is a snippet of my procedure, that does a fade in for a text:

private void fadeColor(Color pOldColor, Color pNewColor) {

int oldRed = pOldColor.getRed();
int oldGreen = pOldColor.getGreen();
int oldBlue = pOldColor.getBlue();

int newRed = pNewColor.getRed();
int newGreen = pNewColor.getGreen();
int newBlue = pNewColor.getBlue();

while ((oldRed != newRed) || (oldGreen != newGreen) || (oldBlue != newBlue)) {

if (oldRed > newRed) {
oldRed--;
} else if (oldRed < newRed) {
oldRed++;
}

if (oldGreen > newGreen) {
oldGreen--;
} else if (oldGreen < newGreen) {
oldGreen++;
}

if (oldBlue > newBlue) {
oldBlue--;
} else if (oldBlue < newBlue) {
oldBlue++;
}

color = new Color(oldRed, oldGreen, oldBlue);

// repaint container
card.repaint();
try {
sleep(20);
} catch (InterruptedException ie) {};

}
}

In this particular case, your fade is somewhat broken. I'm sure it
works (in conjunction with other code) but it goes in extremely small
steps. A fade from pure white to pure black would require 255
iterations and take an absolute minimum of 5.1 seconds. The fade can
also be uneven -- it will not take a linear path from one color to the
other for most starting and ending colors. That's because it takes
steps of the same size for each color component, even though more steps
are likely to be required overall for the different components.

A better strategy is to choose the number of steps to use for fading and
the time per step, then make it happen. Here is part of an
implementation of that approach:

private final static int FADE_STEPS = 16;
private final static int FADE_DELAY = 20;

private void fadeColor(Color oldColor, Color newColor) {
int oldRed = oldColor.getRed();
int oldGreen = oldColor.getGreen();
int oldBlue = oldColor.getBlue();

int diffRed = newColor.getRed() - oldRed;
int diffGreen = newColor.getGreen() - oldGreen;
int diffBlue = newColor.getBlue() - oldBlue;

for (int i = 1; i <= FADE_STEPS; i--) {
Color fadeColor = new Color(
oldRed + (diffRed * i) / FADE_STEPS,
oldGreen + (diffGreen * i) / FADE_STEPS,
oldBlue + (diffBlue * i) / FADE_STEPS);

repaintWithNewColor(fadeColor);
Thread.sleep(FADE_DELAY);
}
}

That's shorter and cleaner, takes a linear path through color space, and
operates in a (more or less) constant time of about one third of a
second. The smoothness and duration of the fade can be adjusted by
varying the FADE_STEPS and FADE_DELAY variables, and if you wanted
different settings for different fades then these could be turned into
parameters to the fadeColor method.

Do note, though, that neither this method nor your version should be
invoked from the event dispatch thread unless it is acceptable for the
GUI to be otherwise frozen while the fade takes place. If you want the
fade to happen concurrently with other GUI activity then you would want
to look into one of the two Timer classes. Probably javax.swing.Timer
would be best if you are already using Swing or are willing to introduce
a dependency on Swing. It gets more complicated otherwise, but should
still be doable.


John Bollinger
(e-mail address removed)
 
J

John C. Bollinger

John said:
private void fadeColor(Color oldColor, Color newColor) {
int oldRed = oldColor.getRed();
int oldGreen = oldColor.getGreen();
int oldBlue = oldColor.getBlue();

int diffRed = newColor.getRed() - oldRed;
int diffGreen = newColor.getGreen() - oldGreen;
int diffBlue = newColor.getBlue() - oldBlue;

for (int i = 1; i <= FADE_STEPS; i--) {
-------------------------------------------^^^

Should be "i++" there, of course. Sorry.


John Bollinger
(e-mail address removed)
 
R

Roedy Green

You should be able to
determine how many you're creating and disposing by simple use of a
profiler.

You could also precompute your colours and store them in an array
rather than computing them afresh.
 
T

Tristan

Hi John,
That's shorter and cleaner, takes a linear path through color space, and
operates in a (more or less) constant time of about one third of a
second. The smoothness and duration of the fade can be adjusted by
varying the FADE_STEPS and FADE_DELAY variables, and if you wanted
different settings for different fades then these could be turned into
parameters to the fadeColor method.

Do note, though, that neither this method nor your version should be
invoked from the event dispatch thread unless it is acceptable for the
GUI to be otherwise frozen while the fade takes place. If you want the
fade to happen concurrently with other GUI activity then you would want
to look into one of the two Timer classes. Probably javax.swing.Timer
would be best if you are already using Swing or are willing to introduce
a dependency on Swing. It gets more complicated otherwise, but should
still be doable.

thank you for your help. The fade looks really good now and I think
you are right. It's better because it's linear.
Well, I guess you are an expert ;-).

Cu, Tristan.
 
T

Tristan

Hi,

now I have another problem that depends on the previous that you
solved.
I don't have a code snippet, but I just need an idea for the following
problem:

I have a fading background, that fades after 20 seconds and is a
thread.
Then I have a text, that fades from the background color to black and
vice versa and is also a thread.
The problem is that, there is the case when the text fades to black
during the fading of the background. If I used the previous procedure
I think it wouldn't look good, because the background color changes
during that time.
My idea is to track the current background color in the loop of the
text thread and reduce the brightness of the color for the text
permanently. I don't know if this is a good solution. Any other ideas
?

Thanks for your help.

Cu, Tristan.
 
J

John C. Bollinger

Tristan said:
now I have another problem that depends on the previous that you
solved.
I don't have a code snippet, but I just need an idea for the following
problem:

I have a fading background, that fades after 20 seconds and is a
thread.
Then I have a text, that fades from the background color to black and
vice versa and is also a thread.
The problem is that, there is the case when the text fades to black
during the fading of the background. If I used the previous procedure
I think it wouldn't look good, because the background color changes
during that time.
My idea is to track the current background color in the loop of the
text thread and reduce the brightness of the color for the text
permanently. I don't know if this is a good solution. Any other ideas
?

I'm not sure I understand the problem very well. It would be possible,
however, to modify the previous code so that it computes the starting
color components and overall differences for each component at each
iteration of the loop, based on whatever the background color is at that
point and the target color. This will not perform as well, but the
extra processing time will probably not be noticeable to the user. You
will, however, want to synchronize the two threads with respect to
reading / changing the background color. The code would be similar; it
is left as an exercise for the reader. :) Does that answer the question?

The alternative, perhaps better, answer is to first try it the way you
have it now and see whether it is satisfactory. If not, then consider
just not doing the kind of multiple fade you describe.


John Bollinger
(e-mail address removed)
 
M

Mladen Adamovic

If he change colors in one loop and then use that loop many times, it is
good to keep all the colors in the array and than work with array index in
every loop exept the first one.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,770
Messages
2,569,584
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top