I'm creating an array of vertex formats which I know will always come in groups of 3 as models are generally made for triangles which have 3 vertices.

My loop was originally

``````for (int i = 0; i < batchVertices.Length; ++i)
{
batchVertices[i] = new VertexFormat(vertices[i], normals[i], textureCoordinates[i]);
}``````

I have now optimised it to the best of my ability

``````for (int i = 0; i < batchVertices.Length; i += 3)
{
int i1 = i + 1;
int i2 = i + 2;

batchVertices[i] = new VertexFormat(vertices[i], normals[i], textureCoordinates[i], textureIndex);
batchVertices[i1] = new VertexFormat(vertices[i1], normals[i1], textureCoordinates[i1], textureIndex);
batchVertices[i2] = new VertexFormat(vertices[i2], normals[i2], textureCoordinates[i2], textureIndex);
}``````

Is there anything else I can do and is the method above a good way of optimising (in your opinion)?

4
Contributors
6
Replies
8
Views
7 Years
Discussion Span
Last Post by Momerath

Hello, as a way of optimization, I'd suggest you to use static members. On every iteration of your cycle, you create again and again new instances of VertexFormat. You can create a static method in this class, so you could do something like that:

``````for (int i = 0; i < batchVertices.Length; ++i)
{
batchVertices[i] = VertexFormat.getBatchVertices(vertices[i], normals[i], textureCoordinates[i]);
}``````

also taking the Length property out of the cycle:

``````uint len = batchVertices.Length;
for (int i = 0; i < len; ++i)
{
//...``````

Also I'd suggest you to try a descending loop (from i=len to 0). Especially, if you can test the time of it's execution (cause I don't have tools right now).

Ok, these probably the most influential .. I'll let you know, if I'd remember something else.

DaveTran: I really dont understand what can be wrong with your original loop.
How long is the "batchVerticles object? it is less then 3? I dont know what you have "optimized" it in the way you did - thats not optimization. Its de-optimization.

Can you please explain bit better, why you dont use your 1st original loop. It doesnt make sence to me (yet).

Mitja Bonca,
by unwrapping a part of loop, DaveTran lessen the cycle iterations in 2 times .. it's one of the known ways to optimize loops. It doesn't look too fancy, but it does optimize it.

Edited by Antenka: n/a

It's known as loop unrolling (or loop unwinding).

One thing you can do is move the `int i1` to outside the loop. I believe the built in optimizer will do that for you, but it doesn't hurt. So your code becomes

``````int i1;
int i2;
int len = batchVertices.Length;
for (int i = 0; i < len; i += 3) {
i1 = i + 1;
i2 = i + 1; ...``````

This saves the stack manipulation. But I'm guessing the costly part of your loop is the object creation and not the loop itself. Are you doing anything interesting in creating the objects, or are you just assigning values to instance variables with no calculations?

Edited by Momerath: n/a

Thank you for the help guys 'n' gals. The current version now looks like

``````batchVertices = new VertexFormat[vertices.Length];
int len = batchVertices.Length;
VertexFormat v = new VertexFormat();

for (int i = 0; i < len; ++i)
{
v.Normal = normals[i];
v.Position = vertices[i];
v.TexCoords = textureCoordinates[i];
batchVertices[i] = v;
}``````

I've removed the unrolling optimisation due to vertex length not always being divisible by 3.

Also I'd suggest you to try a descending loop (from i=len to 0)

How does looping backwards instead of forwards increase speed? It sounds interesting :)

Are you doing anything interesting in creating the objects, or are you just assigning values to instance variables with no calculations?

Just assigning values with no calculations.

Edited by DaveTran: n/a

How does looping backwards instead of forwards increase speed? It sounds interesting :)

Sometimes small changes in code allows the built-in optimizer to vastly improve your code. So trying things like looping backwards, forwards, using while instead of for, trying do/while, etc.

This topic has been dead for over six months. Start a new discussion instead.
Have something to contribute to this discussion? Please be thoughtful, detailed and courteous, and be sure to adhere to our posting rules.