By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
438,737 Members | 1,971 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 438,737 IT Pros & Developers. It's quick & easy.

vm optimizations

P: n/a
i asked something about java optimization before, but i gave a very poor
example... leading to not much help... so here is a better situation.

i have a Map, and i'm constantly picking entries from random from this
map.

in one method, i only use the map.
in another method, i use an array of keys from the map, stored seperately.

method a (only the map):

Map myMap = //initialize map
Object randObj;
// begin loop
randObj = myMap.keySet().toArray()[(int)Math.floor(Math.random() *
myMap.size())];

so, as you can see, in method a i constantly re-acquire the array of
keys... but reduce the clutter.

method b:

Map myMap = //initialize map
Object[] keyArray = myMap.keySet().toArray();
// begin loop
randObj = myMap.get(keyArray[(int)Math.floor(Math.random() *
keyArray.length)]);

the only change then is one single array that has a name.

what i'm wondering is:

does the compiler or runtime environment do any optimizations such that
method a is the same (or better maybe) than method b?

while i know the call stack will be one shorter in method b, i'm really
curious about whether or not method a constantly allocates and frees up
memory for the array.

does anyone know where i can find out about these sorts of issues, or can
anyone clear this example out for me?

thanks much,

murat

--
Murat Tasan
mx**@po.cwru.edu
ta***@eecs.cwru.edu
mu*********@cwru.edu
http://genomics.cwru.edu

Jul 17 '05 #1
Share this Question
Share on Google+
3 Replies


P: n/a
> method a (only the map):

Map myMap = //initialize map
Object randObj;
// begin loop
randObj = myMap.keySet().toArray()[(int)Math.floor(Math.random() *
myMap.size())];

method b:

Map myMap = //initialize map
Object[] keyArray = myMap.keySet().toArray();
// begin loop
randObj = myMap.get(keyArray[(int)Math.floor(Math.random() *
keyArray.length)]);


There seems to be some inconsistency in the nature of the two methods.
While (a) populates randObj with random keys, (b) retrieves values
values based on random keys.
Call stack size wouldn't affect method (a) significantly as the
Map.keySet() method provides you with a collection view of the keys
and doesn't create a new Set as such. The execution efficiency of
method (b) depends on the Map implementation used; eg. a HashMap woul
aloow fster random access than a TreeMap.
You need to be a little clearer in your algorithm.
Jul 17 '05 #2

P: n/a
you're correct, i wrote the example wrong. you jist should've still been
clear... here is the revised line in method a:

randObj = myMap.get(myMap.keySet().toArray()[(int)Math.floor(Math.random()
* myMap.size())]);

(all that was needed was adding a myMap.get(..) statement in front of the
line.

murat

On Thu, 29 Oct 2003, Saager wrote:
method a (only the map):

Map myMap = //initialize map
Object randObj;
// begin loop
randObj = myMap.keySet().toArray()[(int)Math.floor(Math.random() *
myMap.size())];

method b:

Map myMap = //initialize map
Object[] keyArray = myMap.keySet().toArray();
// begin loop
randObj = myMap.get(keyArray[(int)Math.floor(Math.random() *
keyArray.length)]);


There seems to be some inconsistency in the nature of the two methods.
While (a) populates randObj with random keys, (b) retrieves values
values based on random keys.
Call stack size wouldn't affect method (a) significantly as the
Map.keySet() method provides you with a collection view of the keys
and doesn't create a new Set as such. The execution efficiency of
method (b) depends on the Map implementation used; eg. a HashMap woul
aloow fster random access than a TreeMap.
You need to be a little clearer in your algorithm.


--
Murat Tasan
mx**@po.cwru.edu
ta***@eecs.cwru.edu
mu*********@cwru.edu
http://genomics.cwru.edu

Jul 17 '05 #3

P: n/a
Murat Tasan wrote:
i asked something about java optimization before, but i gave a very poor
example... leading to not much help... so here is a better situation.

i have a Map, and i'm constantly picking entries from random from this
map.

in one method, i only use the map.
in another method, i use an array of keys from the map, stored seperately.

method a (only the map):

Map myMap = //initialize map
Object randObj;
// begin loop
randObj = myMap.keySet().toArray()[(int)Math.floor(Math.random() *
myMap.size())];

so, as you can see, in method a i constantly re-acquire the array of
keys... but reduce the clutter.

method b:

Map myMap = //initialize map
Object[] keyArray = myMap.keySet().toArray();
// begin loop
randObj = myMap.get(keyArray[(int)Math.floor(Math.random() *
keyArray.length)]);

the only change then is one single array that has a name.

what i'm wondering is:

does the compiler or runtime environment do any optimizations such that
method a is the same (or better maybe) than method b?

while i know the call stack will be one shorter in method b, i'm really
curious about whether or not method a constantly allocates and frees up
memory for the array.

does anyone know where i can find out about these sorts of issues, or can
anyone clear this example out for me?


Murat,

I cannot say anything for certain; but my expectation is that the
compiler optimizations will not yield the same or equivalent code here.
The main reason is that it is possible for another thread to change
the Map during the loop. If this happens, the behavior of the two
methods will be different.

BTW, a means of improving the performance of the first method without
changing the way it works (assuming that is desirable) would be to
allocate the array only once and re-use the array reference. E.g.

Object keyArr[] = new Object[myMap.size()];
for (;;)
{
keyArr = myMap.keySet.toArray(keyArr);
randObj = myMap.get(keyArr[(int)(Math.random()*keyArr.length]);
}

Ray

Jul 17 '05 #4

This discussion thread is closed

Replies have been disabled for this discussion.