The compiler would actually be forbidden from optimizing it in many cases, as C functions are not guaranteed to be pure. Only if the function is visible and can be inlined and it can be proven there is no aliasing there is a reasonable chance for it to be optimized.
Exactly. While this is Java, I prefer to be explicit with my intentions instead of hoping the JIT will do The Right Thing™. I got enough indirection as it is, and this tiny bit of code is literally the step before issuing all the draw calls. It shouldn't waste time.
Why do you have a local variable named queue (and nothing else), hungarian notation is bad, yet it gives you the type and intent, the type is too much but here you have "only" the type, and you even have the wrong one as it's an array and not a queue, i can't think of any worse variable name.
Whoa man, relax for a bit. "Queue" isn't the type. As you see its a plain array, so the name tells you how it should be treated, processed from 0 to (size-1), like a queue. That's why named it queue instead of, say, bananas. I'll give you that, 'tasks' can be a better name. That bit is a leftover from the previous iteration on the drawing method, they were "RenderInstances" instead of RenderTasks and "instances" sounded silly (like calling an object 'object').
The issue in that piece of code aren't the variable names. They're literally defined 5 lines above, you can't miss them. They follow a very simple pattern, array declaration then size declaration, repeat for everything that will be iterated on. Then there is 'mbs' just so the VM doesn't dares to fetch the value from main memory again. They're all single purpose, limited only to that method.
Problem here is the horrible nested loop logic that depends on like 4 different conditions. That's why the rest of the variables have more complete names (maxInstance, lastItem, completedLastTask, etc) and why you have comments in that section, because that is the complex part, not the damn for-loop declaration. There are no variable naming scheme in the world that will save you from trying to debug that mess.
If you want to bike-shed the variable names that's fine but its definitively not the time I end up spending on when I try to understand these kind of things. Specially if all the variables being used are orderly declared at the beginning of the method, as I said, very hard to miss. Its an idiom that some languages even support directly by disallowing variable declarations in the middle of the block.
the rest of the code is also pretty bad as it seems you're trying to use the arrays as queues, why aren't you simply actually using a queue then instead of all the cryptic special case looping code?
Bag is a list with a simple array as backing storage. The reason behind using the backing arrays directly is that they're easier to "understand" by the JIT, there are no class hierarchies to check nor methods to try to inline, just direct array access.
Since Bag can be used like anything, "queue" communicates how it should be treated. Why I don't use a Queue class or something? Because I already got Bag, and it works. Bag is made to be used as you see fit. In this case its essentially used simply to dynamically resize the backing array as needed, since all I use is the bag.add(item) and bag.clear() methods.
Why I don't use standard Java collections? Because they don't allow you to grab the backing array for fast iteration, and they don't contain "unsafe" methods that don't do internal size checks, unlike Bag.
Cryptic "special case looping" has nothing to do with queue and all to do with all the things its tracking. Current task, current instance of the task, tasks left, instances left from the previous task, current index to start from in the draw call, etc. Everything has to be accounted for or you end up without nice efficient batching. Its shit, but its doing good and important stuff well.