for:each loops versus standard loops

I 'd strongly recommend for List or Map instances to Iterate on them if you intend to bring up more as one single Thread on it. Then for:each loop is obviously the only way to make it on running while you mustn’t forget about synchronizing all that stuff. Javadoc manner provides a synchronized view of every sort of Array from the Collections static class. See:

Map<Integer, Object> smap = Collections.synchronizedMap(new HasMap<Integer, Object>());
synchronized(smap) {
     for(Iterator<Integer> i = smap.keySet().iterator(); i.hasNext())
             doSomeActionOnTheValue(smap.get(i.next()));
}

This will run as fast as if you had one Object[] array to initialize and to get activity running on it. The obvious advantage with Maps or List or Set, globally Collections, is to have a scaleable amount of values to work on. ::slight_smile:

@broumbroum
I think you missed the point, that this is a performance discussion… ::slight_smile:

either I don’t get it due to language barrier or this statement is a plain lie :o

I assume you don’t even have ever tried it, but it is true that this is the fastest way to get out of for and foreach loops with big amount of objects. :stuck_out_tongue:

bullshit :slight_smile: plain lie :stuck_out_tongue:

Collections are slower to iterate - especially in a for-each (simply because doing it yourself removes the overhead of the Iterator)

So did you?


[forward1] for(int i=0;i<a.size();i++)
best:0.401326985s
avg :0.424093174s

[forward2] int size=a.size();for(int i=0;i<size;i++)
best:0.37795893s
avg :0.401431877s

[reverse1] for(int i=a.size()-1;i>=0;--i)
best:0.369816555s
avg :0.389192799s

[reverse2] for(int i=a.size();--i>=0;)
best:0.361338383s
avg :0.390844695s

[iterate]  for(Iterator i=a.iterator();i.hasNext();)
best:1.039801428s
avg :1.116375577s

[foreach]  for(Integer s: a)
best:1.087047935s
avg :1.138143202s

[synchro1] for(Iterator<Integer> i = sa.iterator(); i.hasNext();) // one synchronizedList() call
best:1.050037086s
avg :1.143322395s

[synchro2] for(Iterator<Integer> i = sa.iterator(); i.hasNext();) // multiple synchronizedList() calls (one per test iteration)
best:1.088886716s
avg :1.14673606s

Testcase:


public class IterationTester
{
	int LIST_SIZE=4096;
	int ITERATIONS=5000;
	int REPEAT=20;
	int AVG=REPEAT/2;
	ArrayList<Integer> a=new ArrayList(LIST_SIZE);
	long []times=new long[8];
	long []avg=new long[8];
	public static void main(String[]args){
		new IterationTester();
	}
	public IterationTester(){
		for(int i=0;i<LIST_SIZE;i++)
			a.add(new Integer(i));
		for(int i=0;i<times.length;i++)
			times[i]=Long.MAX_VALUE;
		long start;
		long stop;
		long time;
		for(int i=0;i<REPEAT;i++){
			if(i==AVG)
				for(int k=0;k<times.length;k++)
					avg[k]=times[k];

			start=System.nanoTime();
			forward1();
			stop=System.nanoTime();
			time=stop-start;
			avg[0]=(avg[0]*AVG+(time))/(AVG+1);
			System.out.println("forward1 "+time/1000000000.0+"s");
			if(time<times[0])
				times[0]=time;

			start=System.nanoTime();
			forward2();
			stop=System.nanoTime();
			time=stop-start;
			avg[1]=(avg[1]*AVG+(time))/(AVG+1);
			System.out.println("forward2 "+time/1000000000.0+"s");
			if(time<times[1])
				times[1]=time;

			start=System.nanoTime();
			reverse1();
			stop=System.nanoTime();
			time=stop-start;
			avg[2]=(avg[2]*AVG+(time))/(AVG+1);
			System.out.println("reverse1 "+time/1000000000.0+"s");
			if(time<times[2])
				times[2]=time;

			start=System.nanoTime();
			reverse2();
			stop=System.nanoTime();
			time=stop-start;
			avg[3]=(avg[3]*AVG+(time))/(AVG+1);
			System.out.println("reverse2 "+time/1000000000.0+"s");
			if(time<times[3])
				times[3]=time;

			start=System.nanoTime();
			iterate();
			stop=System.nanoTime();
			time=stop-start;
			avg[4]=(avg[4]*AVG+(time))/(AVG+1);
			System.out.println("iterate "+time/1000000000.0+"s");
			if(time<times[4])
				times[4]=time;

			start=System.nanoTime();
			foreach();
			stop=System.nanoTime();
			time=stop-start;
			avg[5]=(avg[5]*AVG+(time))/(AVG+1);
			System.out.println("foreach "+time/1000000000.0+"s");
			if(time<times[5])
				times[5]=time;

			start=System.nanoTime();
			synchro1();
			stop=System.nanoTime();
			time=stop-start;
			avg[6]=(avg[6]*AVG+(time))/(AVG+1);
			System.out.println("synchro1 "+time/1000000000.0+"s");
			if(time<times[6])
				times[6]=time;

			start=System.nanoTime();
			syncro2();
			stop=System.nanoTime();
			time=stop-start;
			avg[7]=(avg[7]*AVG+(time))/(AVG+1);
			System.out.println("synchro2 "+time/1000000000.0+"s");
			if(time<times[7])
				times[7]=time;
		}
		String []labels={
			"[forward1] for(int i=0;i<a.size();i++)",
			"[forward2] int size=a.size();for(int i=0;i<size;i++)",
			"[reverse1] for(int i=a.size()-1;i>=0;--i)",
			"[reverse2] for(int i=a.size();--i>=0;)",
			"[iterate]  for(Iterator i=a.iterator();i.hasNext();)",
			"[foreach]  for(Integer s: a)",
			"[synchro1] for(Iterator<Integer> i = sa.iterator(); i.hasNext();) // one synchronizedList() call",
			"[synchro2] for(Iterator<Integer> i = sa.iterator(); i.hasNext();) // multiple synchronizedList() calls (one per test iteration)"
		};
		for(int i=0;i<times.length;i++){
			System.out.println(labels[i]);
			System.out.println("best:"+times[i]/1000000000.0+"s");
			System.out.println("avg :"+avg[i]/1000000000.0+"s");
			System.out.println();
		}
	}
	public void forward1(){
		int sum=0;
		for(int x=0;x<ITERATIONS;x++)
			for(int i=0;i<a.size();i++)
				sum+=((Integer)a.get(i)).intValue();
	}
	public void forward2(){
		int sum=0;
		int size=a.size();
		for(int x=0;x<ITERATIONS;x++)
			for(int i=0;i<size;i++)
				sum+=((Integer)a.get(i)).intValue();
	}
	public void reverse1(){
		int sum=0;
		for(int x=0;x<ITERATIONS;x++)
			for(int i=a.size()-1;i>=0;--i)
				sum+=((Integer)a.get(i)).intValue();
	}
	public void reverse2(){
		int sum=0;
		for(int x=0;x<ITERATIONS;x++)
			for(int i=a.size();--i>=0;)
				sum+=((Integer)a.get(i)).intValue();
	}
	public void iterate(){
		int sum=0;
		for(int x=0;x<ITERATIONS;x++)
			for(Iterator i=a.iterator();i.hasNext();)
				sum+=((Integer)i.next()).intValue();
	}
	public void foreach(){
		int sum=0;
		for(int x=0;x<ITERATIONS;x++)
			for(Integer s: a)
				sum+=s.intValue();
	}
	public void synchro1(){
		int sum=0;
		for(int x=0;x<ITERATIONS;x++)
		{
			List<Integer> sa = Collections.synchronizedList(a);
			synchronized(sa) {
					 for(Iterator<Integer> i = sa.iterator(); i.hasNext();)
						 sum+=((Integer)i.next()).intValue();
			}
		}
	}
	public void syncro2(){
		int sum=0;
		List<Integer> sa = Collections.synchronizedList(a);
		for(int x=0;x<ITERATIONS;x++)
		{
			synchronized(sa) {
				for(Iterator<Integer> i = sa.iterator(); i.hasNext();)
					sum+=((Integer)i.next()).intValue();
			}
		}
	}
}

It’s quite brazen to accuse someone not doing his homework right, if you didn’t yourself :stuck_out_tongue:

thank you for this test, I did my own for my own apps. :wink:

care to post it here and back up your statements?

my results:
java 6 client


[forward1] for(int i=0;i<a.size();i++)
best:0.236861869s
avg :0.237710407s

[forward2] int size=a.size();for(int i=0;i<size;i++)
best:0.243388188s
avg :0.245275719s

[reverse1] for(int i=a.size()-1;i>=0;--i)
best:0.234105232s
avg :0.236468176s

[reverse2] for(int i=a.size();--i>=0;)
best:0.234173636s
avg :0.23560745s

[iterate]  for(Iterator i=a.iterator();i.hasNext();)
best:1.001008995s
avg :1.002553588s

[foreach]  for(Integer s: a)
best:1.001137343s
avg :1.002832611s

[synchro1] for(Iterator<Integer> i = sa.iterator(); i.hasNext();) // one synchronizedList() call
best:1.047498371s
avg :1.050345237s

[synchro2] for(Iterator<Integer> i = sa.iterator(); i.hasNext();) // multiple synchronizedList() calls (one per test iteration)
best:1.026651229s
avg :1.034549709s

java 7b12 client


[forward1] for(int i=0;i<a.size();i++)
best:0.098598338s
avg :0.099309703s

[forward2] int size=a.size();for(int i=0;i<size;i++)
best:0.086764429s
avg :0.087365481s

[reverse1] for(int i=a.size()-1;i>=0;--i)
best:0.086961825s
avg :0.087888956s

[reverse2] for(int i=a.size();--i>=0;)
best:0.087148515s
avg :0.087648407s

[iterate]  for(Iterator i=a.iterator();i.hasNext();)
best:0.902982435s
avg :0.9046512s

[foreach]  for(Integer s: a)
best:0.901919269s
avg :0.904204496s

[synchro1] for(Iterator<Integer> i = sa.iterator(); i.hasNext();) // one synchronizedList() call
best:0.88929315s
avg :0.898148557s

[synchro2] for(Iterator<Integer> i = sa.iterator(); i.hasNext();) // multiple synchronizedList() calls (one per test iteration)
best:0.887476421s
avg :0.901809679s


java 6 server


[forward1] for(int i=0;i<a.size();i++)
best:0.047897427s
avg :0.04833437s

[forward2] int size=a.size();for(int i=0;i<size;i++)
best:0.047876021s
avg :0.048443501s

[reverse1] for(int i=a.size()-1;i>=0;--i)
best:0.050514161s
avg :0.051226223s

[reverse2] for(int i=a.size();--i>=0;)
best:0.050541038s
avg :0.051425828s

[iterate]  for(Iterator i=a.iterator();i.hasNext();)
best:0.170091701s
avg :0.171224648s

[foreach]  for(Integer s: a)
best:0.17041104s
avg :0.171149453s

[synchro1] for(Iterator<Integer> i = sa.iterator(); i.hasNext();) // one synchronizedList() call
best:0.170544356s
avg :0.171396083s

[synchro2] for(Iterator<Integer> i = sa.iterator(); i.hasNext();) // multiple synchronizedList() calls (one per test iteration)
best:0.169996068s
avg :0.17115992s

java 7b12 server (tiered compiler)


[forward1] for(int i=0;i<a.size();i++)
best:0.046119653s
avg :0.046703256s

[forward2] int size=a.size();for(int i=0;i<size;i++)
best:0.046233412s
avg :0.046704791s

[reverse1] for(int i=a.size()-1;i>=0;--i)
best:0.048204308s
avg :0.048780098s

[reverse2] for(int i=a.size();--i>=0;)
best:0.048143243s
avg :0.048854144s

[iterate]  for(Iterator i=a.iterator();i.hasNext();)
best:0.078269895s
avg :0.07890705s

[foreach]  for(Integer s: a)
best:0.078561754s
avg :0.079460743s

[synchro1] for(Iterator<Integer> i = sa.iterator(); i.hasNext();) // one synchronizedList() call
best:0.074725515s
avg :0.076259373s

[synchro2] for(Iterator<Integer> i = sa.iterator(); i.hasNext();) // multiple synchronizedList() calls (one per test iteration)
best:0.079357871s
avg :0.080087159s


CPU: Core2Duo; 64bit winXP; 32bit VMs

I did the test primary because I was curious how the tiered compiler performs compared to the old server VM.

Because i always use the server VM for my 3D stuff, i will use the plain old for loop (for(int i=0;i<a.size();i++) )in future too. But the really interesting part of this benchmark:
-the 7 client VM solves the for loop 2x faster then the 6
-the new tiered VM is even a little bit faster then the old server VM

:slight_smile: thats looking pritty sharp