Hi, I confirm your results. I didn't think there could be a difference using foreach constructs...
Cedric Steven A Rowe wrote: > > On 04/04/2008 at 4:40 AM, Toke Eskildsen wrote: >> On Wed, 2008-04-02 at 09:30 -0400, Mark Miller wrote: >> > > - replacement of indexed for loops with for each constructs >> > >> > Is this always the best idea? Doesn't the for loop construct make an >> > iterator, which can be much slower than an indexed for loop? >> >> Only in the case of iterations over collections. For arrays, the foreach >> is syntactic sugar for indexed for-loop. >> http://java.sun.com/docs/books/jls/third_edition/html/statements.html#14.14.2 > > I don't think this is actually true. The text at the above-linked page > simply says that for-each over an array "means the same as" an indexed > loop over the same array. "Syntactic sugar", OTOH, implies that the > resulting opcode is exactly the same. When I look at the byte code (using > javap) for the comparison test I include below, I can see that the indexed > and for-each loops do not generate the same byte code. > > I constructed a simple program to compare the runtime length of the two > loop control mechanisms, while varying the size of the array. The test > program takes command line parameters to control which loop control > mechanism to use, the size of the array (#elems), and the number of times > to execute the loop (#iters). I used a Bash shell script to invoke the > test program. > > Summary of the results: over int[] arrays, indexed loops are faster on > arrays with fewer than about a million elements. The fewer the elements, > the faster indexed loops are relative to for-each loops. This could be > explained by a higher one-time setup cost for the for-each loop - above a > certain array size, the for-each setup cost is lost in the noise. It > should be noted, however, that this one-time setup cost is quite small, > and might be worth the increased code clarity. > > Here are the results for three different platforms: > > - Best of five iterations for each combination > - All using the -server JVM option > - Holding constant #iters * #elems = 10^10 > - Rounding the reported real time to the nearest tenth of a second > - "% Slower" = 100 * ((For-each - Indexed) / Indexed) > > Platform #1: Windows XP SP2; Intel Core 2 duo [EMAIL PROTECTED]; Java 1.5.0_13 > > #iters #elems For-each Indexed % Slower > ------ ------ -------- ------- -------- > 10^9 10^1 22.3s 13.8s 62% > 10^8 10^2 16.0s 13.6s 18% > 10^6 10^4 14.8s 13.0s 14% > 10^4 10^6 12.9s 12.9s 0% > 10^3 10^7 13.4s 13.3s 1% > > Platform #2: Debian Linux, 2.6.21.7 kernel; Intel Xeon [EMAIL PROTECTED]; Java > 1.5.0_14 > > #iters #elems For-each Indexed % Slower > ------ ------ -------- ------- -------- > 10^9 10^1 33.6s 14.2s 137% > 10^8 10^2 20.4s 13.9s 47% > 10^6 10^4 19.0s 12.7s 50% > 10^4 10^6 12.7s 12.8s -1% > 10^3 10^7 13.2s 13.2s 0% > > Platform #3: Debian Linux, 2.6.21.7 kernel; Intel Xeon [EMAIL PROTECTED]; Java > 1.5.0_10 > > #iters #elems For-each Indexed % Slower > ------ ------ -------- ------- -------- > 10^9 10^1 102.7s 73.6s 40% > 10^8 10^2 107.8s 60.0s 80% > 10^6 10^4 105.2s 58.6s 80% > 10^4 10^6 58.8s 53.0s 11% > 10^3 10^7 60.0s 54.1s 11% > > > ----- ForEachTest.java follows ----- > > import java.util.Date; > import java.util.Random; > > /** > * This is meant to be called from a shell script that varies the loop > style, > * the number of iterations over the loop, and the number of elements in > the > * array over which the loop iterates, e.g.: > * > * cmd="java -server -cp . ForEachTest" > * for elems in 10 100 10000 1000000 10000000 ; do > * iters=$((10000000000/${elems})) > * for run in 1 2 3 4 5 ; do > * time $cmd --indexed --arraysize $elems --iterations $iters > * time $cmd --foreach --arraysize $elems --iterations $iters > * done > * done > * > */ > public class ForEachTest { > static String NL = System.getProperty("line.separator"); > static String usage > = "Usage: java -server -cp . ForEachTest [ --indexed | --foreach ]" > + NL + "\t--iterations <num-iterations> --arraysize <array-size>"; > > public static void main(String[] args) { > boolean useIndexedLoop = false; > int size = 0; > int iterations = 0; > try { > for (int argnum = 0 ; argnum < args.length ; ++argnum) { > if (args[argnum].equals("--indexed")) { > useIndexedLoop = true; > } else if (args[argnum].equals("--foreach")) { > useIndexedLoop = false; > } else if (args[argnum].equals("--iterations")) { > iterations = Integer.parseInt(args[++argnum]); > } else if (args[argnum].equals("--arraysize")) { > size = Integer.parseInt(args[++argnum]); > } else { > throw new Exception("Unknown cmdline parameter '" > + args[argnum] + "'."); > } > } > } catch (Exception e) { > System.err.println("Error parsing command line: " + e + NL); > System.err.println(usage); > System.exit(1); > } > > // Initial the array with random integers > int[] array = new int[size]; > Random random = new Random(); > for (int i = 0 ; i < size ; ++i) { > array[i] = random.nextInt(); > } > > int k = 0; > if (useIndexedLoop) { > System.out.println("Indexed : " + iterations + " iterations : " > + size + " elements"); > for (int m = 0 ; m < iterations ; ++m) { > for (int j = 0 ; j < size ; ++j) { > k = array[j]; > } > } > } else { // useIndexedLoop = false > System.out.println("For-each : " + iterations + " iterations : " > + size + " elements"); > for (int m = 0 ; m < iterations ; ++m) { > for (int j : array) { > k = j; > } > } > } > k = 0; > } > } > > --------------------------------------------------------------------- > To unsubscribe, e-mail: [EMAIL PROTECTED] > For additional commands, e-mail: [EMAIL PROTECTED] > > > -- View this message in context: http://www.nabble.com/-jira--Created%3A-%28LUCENE-1257%29-Port-to-Java5-tp16445478p16587806.html Sent from the Lucene - Java Developer mailing list archive at Nabble.com. --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]