There is actually another optimization in the above example. The lookup of the length of a is only done once in the second example which also improves the speed, probably more than the test against zero optimization does.

For the record, I consider the follower to be even more optimized but I've found it makes the code harder to read so I never use it.

Good idea to post these kinds of things. Who knows, it might help.But, to make the tests more comparable and help to relativise, we should know the jvm you tested this against, and if that performance was tested in a full program, or just a bench.

I don't have any numbers. I've yet to find a way to reliably reproduce performance numbers on a micro benchmark. I will say I mentioned this to the author of idx3d back in 2000 and he thought it was an improvement enough to mention me in the source code and he replied back with an email basicly saying "that was the single most effective optimization I've done." At the time his target JVM was the one with Internet Exploder and Nutscrape 4.

I have yet to see a place where making your booleans test againt zero is slower, so I'd say it can't hurt the performance level. Like I said, it's my pet optimization. You're free to take it or leave it.

I was under the impression that the counting backwards trick was only useful on older 386/486 chips. Due to an unfortunate me v. powertool accident last night I had some extra time to run this test today. In my little tests method A was faster than the other two methods. I didn't do anything in the loop.

Timers are in nanoseconds as reported by J3DTimer with a resolution of 3ns. All methods were run 20 times with only the last ten runs being recorded.

I took the code from IDX3D can converted the for loops to Method A, they were alread in method B, and ran a few tests. You can download the code I used at: http://flick.nerdc.ufl.edu/IDXBench/ I gotta run so I can't do the math but here is enough output for you to play with. The output is the sample # and then FPS taken every 25 seconds. The test was run on a linux box with no other activity.

I played around with such optimizations some time ago for my own software renderer (similar to IDX3D, but better of course... ) and i was unable to meassure a postive effect of this optimization. A problem is, that you usually access the array in the "do stuff" section and it is far more cache friendly if you do this from start to end than backwards. So i ended up being slower sometimes when doing this "optimization". Another idea i tried was to put "do stuff" in an endless loop and let Java's range checking on arrays (takes place anyway) terminate it by generating an exception which i caught with a try-catch around that loop. Look ugly, feels ugly, should be faster but wasn't.

...where you use 'j' (not 'i') as your regular loop counter (then you don't have to reverse your arrays or anything).

This seems like such a general case that I'd be tempted to think compilers could optimize this like this anyway, but then again they're probably not sure whether 'a.length' will remain constant for every iteration of the loop (unless it was declared final or something).

I agree with leknor that most machine languages have special instructions for testing zero, as opposed to loading a value into a register (which itself may require a function call or two) and then checking it.

Mind you, these sorts of micro optimizations are pretty academic - they're harder to read and not going to gain you anything over simply writing a better algorithm

The conclusions i can take out of these tests:- read arrays from the beginning to the end- these optimisations don't seem to be interesting.

The questions i have are: is the jvm testing at 0 using a special instruction, or does it use the standard, and loads 0 into a register prior testing? that would explain why there are no differences, if it can. We can also argue that register loading could take no time, if done in an other pipeline of the processor, bla bla bla... [paste the code for endless discussion here]

The JVM does not "use" a special instruction to test against 0. Although it has one, it's turned quite readily into whatever the fastest way to test it is on current hardware. As far as I am aware, the current Pentium 2/3/4 chips execute nearly all of their basic instructions in a single cycle somewhere deep in a pipe. There is, effectively, no performance difference, excepting that Hotspot probably tries to do its bounds checking on the cheap by looking for the common case of counting from 0..n.

Not too long ago this was a valid performance optimisation, but not any more. Not too long ago it was faster to do maths using fixed point integer representations, but not any more. Unless you're working on ARM chips of course

On the pipeline story, even if the register is loaded using an other pipeline, you still have some overhead ( (eventual) save register to stack, load register, compare, (eventual) reload register from stack ) compared to normal one (compare)Instructions of one cycle should not be pipelined, so the pipes are free for long operations. Thus, if they don't compare with special instructions, it will still take more time.Would be nice to get the info from the jjit team.

You don't have to do an explicit compare to 0. Just decrement the register (loop counter) and do a jnz (jump not zero) or a jns (jump not signed) to the start of the loop. If the register/counter reaches 0 then (or -1), the loop won't be taken because the zero-flag/signed-flag is set and you are done.

On x86, what is the register that is used for jumps?As far as i remember, opposed to 68xxx, x86 have specialized registers. Are you sure this register would be useable to do all operations needed? If it needs to be pushed, popped from an other one in the loop, of course, the gain would be null.

You can use the standard registers (eax, ebx, ecx, edx) without problems for this. The main problem is the very limited number of registers on x86. You have to use your registers clever to optimize such things if the code inside the loop gets more complex.

Correct, but (as i mentioned above) this is not an optimized way of doing it in a loop, because a compare to 0 isn't different from a compare to X in this example. The actual optimization is to get rid of the "cmp" in the loop.

I may be looking at this the wrong way, but are you actually checking for zero in this loop? It would seem that you are looking for i to be less than 0 which is a different check. "i >= 0" is much different than "i == 0" or "i != 0".

That's my point. You were talking about optimizing for "i == 0" when 0 needs to be included in the indexing. If the whole optimization is about "i == 0" then the whole way the code is written would need to be changed. Unless you were just being brief when talking about chips being able to test for 0 quickly. "i >= 0" doesn't test for that equality, rather it's a different test entirely. If I'm remembering my Assembly correctly (I only worked with it for a few months), then the test "i >= 0" results in a call to "GE" and a subsequent conditional jump rather than the clean "JZ". To halt execution of the loop when the counter equals 0 would make something odd looking like:[Code]int a[] = new int[1000000]; for (int i = a.length; i != 0; i--){ // Do stuff (While remembering that you// have to subtract one to index the array)} [/Code]Now I'm either off of my nut or it would be very hard to implement this optimization even in a language where you'd be guarenteed that the resulting compile would use the specific chip optimization.

Oh, i see.Look at answer number 16 in this thread. Both operations can be done the same at assembly level.In fact, the topic seemed to have quickly slippped away from "i==0" tests to 'i and special cases (0 or -1)" tests.

chrisbliss18: no problem dude. I almost couldn't find those urls and I was about to get unsure that my facts were straight. It's good for me to go back to my sources every once and a while to make sure I'm not dreaming up things that aren't there.

java-gaming.org is not responsible for the content posted by its members, including references to external websites,
and other references that may or may not have a relation with our primarily
gaming and game production oriented community.
inquiries and complaints can be sent via email to the info‑account of the
company managing the website of java‑gaming.org