Avoiding creation of Color object

I’m not discussing the desing decisions which made Color immutable, I’m just saying that making it mutable will break things in our implementation.

Here’s one example of some code we have in
Graphics2D.setColor(Color newColorObject)


if (newColorObject == alreadySetColor)
  return;
alreadySetColor = newColorObject;
rgbValue= newColorObject.getRgb();

and then later this int rgb value is used all over.
So, if you modify the Color object and try to set it again, it’ll be rejected since we’ll thing it’s aready set. Also, since rgbValue is cached, the graphics context won’t notice that you’ve changed the color object’s value.

This is just one example which is easy to work around once you know about it, but I wouldn’t dare to say it’ll be the last one. Needless to point, that any such workarounds would not be guaranteed to work across releases or different vm versions.

And, I’ll repeat, I’m still not convinced that the creation of Color objects is a problem with your app as I haven’t seen any proof yet. =)

Want some proof :wink: ?

I’ve just made two tests. One with Color creation, one with color caching.

Here are the result (drawing time displayed, and -verbosegc in jvm option)

With Color caching :

Draw Time : 290
Draw Time : 270
Draw Time : 270
Draw Time : 290
Draw Time : 271
Draw Time : 280
Draw Time : 280
Draw Time : 250
Draw Time : 281
Draw Time : 251

Min : 250; Max : 290

With “Dynamic” Color :

[GC 2275K->1635K(9736K), 0.0018497 secs]
[GC 2275K->1635K(9736K), 0.0012935 secs]
[GC 2275K->1635K(9736K), 0.0013415 secs]
Draw Time : 330
[GC 2275K->1635K(9736K), 0.0015390 secs]
[GC 2275K->1635K(9736K), 0.0012982 secs]
[GC 2275K->1635K(9736K), 0.0012909 secs]
[GC 2275K->1635K(9736K), 0.0015237 secs]
Draw Time : 311
[GC 2275K->1635K(9736K), 0.0013256 secs]
[GC 2275K->1635K(9736K), 0.0014139 secs]
[GC 2275K->1635K(9736K), 0.0021162 secs]
Draw Time : 320
[GC 2275K->1635K(9736K), 0.0013516 secs]
[GC 2275K->1635K(9736K), 0.0013242 secs]
[GC 2275K->1635K(9736K), 0.0013158 secs]
Draw Time : 321
[GC 2275K->1635K(9736K), 0.0014820 secs]
[GC 2275K->1635K(9736K), 0.0013382 secs]
[GC 2275K->1635K(9736K), 0.0014234 secs]
[GC 2275K->1635K(9736K), 0.0013158 secs]
Draw Time : 310
[GC 2275K->1635K(9736K), 0.0013270 secs]
[GC 2275K->1635K(9736K), 0.0019173 secs]
[GC 2275K->1635K(9736K), 0.0017782 secs]
Draw Time : 320
[GC 2275K->1635K(9736K), 0.0014256 secs]
[GC 2275K->1635K(9736K), 0.0014493 secs]
[GC 2275K->1635K(9736K), 0.0013700 secs]
Draw Time : 301
[GC 2275K->1635K(9736K), 0.0014474 secs]
[GC 2275K->1635K(9736K), 0.0013697 secs]
[GC 2275K->1635K(9736K), 0.0013683 secs]
[GC 2275K->1635K(9736K), 0.0013147 secs]
Draw Time : 301
[GC 2275K->1635K(9736K), 0.0013929 secs]
[GC 2275K->1635K(9736K), 0.0013558 secs]
[GC 2275K->1635K(9736K), 0.0011873 secs]
Draw Time : 300
[GC 2275K->1635K(9736K), 0.0010923 secs]
[GC 2275K->1635K(9736K), 0.0013901 secs]
[GC 2275K->1635K(9736K), 0.0011163 secs]
Draw Time : 320

Min : 300; Max : 330

Best difference : 80 ms. Worst difference : 10 ms. Moreover, garbage collection in the second case.

Notice that in the second case, additionnal calculus is performed (as it has to determine the color value).

I can precompute the calculus though. But if I precompute the calculus, I can also directly precompute the Colors (a 64-only precomputed-Colors array is ok).

-> I’m gonna implement a ColorCache class which holds a precomputed-Colors array, just as you guys said at the beginning of the thread. I think it’s the best solution.

DoronBarak, your solution (Colour class with cacheColorField) is great, and I may use it for other programs.

Thanks to all ! (discussion may continue if you want)