m_numLoadedAssets is a member of some unnamed class the snipet of code is extracted from. When you call the method, it is likely deeper in the stack than any local variable, or even in the heap.
It depends where *this is allocated. In the worst case, it is allocated in main memory while you wanted to stay in the graphic memory, or something.
A naive compiler would then access memory (or the cache) instead of using registers. A Sufficiently Advanced Compiler would guess that calling ++ many times is the same as incrementing in one go, and hoist that out of the loop, but apparently this one is a bit cruder.
Now the same could be said about m_numAssets, but this one isn't written to, so the compiler only have to put a copy in a register, which I guess is a simpler optimization to do.
To answer your question, that particular situation would be better in any language that forces you to explicit the reference to "this" (or "self"). Imagine how we could modify C++:
void member_function() {
int local_variable++;
local_variable++; // This is okay
member_variable++; // That should not be allowed
this->member_variable++; // This should be written instead
}
Applied to the example in the GGP above:
void load(Assets* a) {
for (int j=0; j<this->m_numAssets; j++) {
loadAsset(a[j]);
this->m_numLoadedAssets++;
}
}
We see that every non-local access is prefixed by something ("this->" and "a[" here). The heavier syntax suggests a heavier cost, so the programmer will more easily think of hoisting those out of the loop, if possible (either manually or through compiler optimizations).
It depends where *this is allocated. In the worst case, it is allocated in main memory while you wanted to stay in the graphic memory, or something.
A naive compiler would then access memory (or the cache) instead of using registers. A Sufficiently Advanced Compiler would guess that calling ++ many times is the same as incrementing in one go, and hoist that out of the loop, but apparently this one is a bit cruder.
Now the same could be said about m_numAssets, but this one isn't written to, so the compiler only have to put a copy in a register, which I guess is a simpler optimization to do.