This site uses strictly necessary cookies. More Information

X- Home /

# Profiler shows Object.ElementAddr_3_8() called over a million times. What is it? How do I reduce this?

I'm working on a voxel game, and in the profiler, under `ChunkBehavior.CreateMeshAndCollision()`

, I see that `Object.ElementAddr_3_8()`

is called tens of thousand of times per call of `CreateMeshAndCollision()`

. It's creating over 70ms of delay every time I create new chunks, making my game stutter. Any idea why `Object.ElementAddr_3_8()`

is being called so many times?

I appreciate any help. I've dropped my `CreateMeshAndCollision()`

method below, if you'd like to take a look at it. Thanks!

```
public void CreateMeshAndCollision() {
vertices = new List<Vector3>();
triangles = new List<int>();
ChunkBehavior topNeighbor = tb.GetChunk(transform.position.x, transform.position.y + SIZE, transform.position.z);
ChunkBehavior bottomNeightbor = tb.GetChunk(transform.position.x, transform.position.y - SIZE, transform.position.z);
ChunkBehavior posXNeighbor = tb.GetChunk(transform.position.x + SIZE, transform.position.y, transform.position.z);
ChunkBehavior negXNeighbor = tb.GetChunk(transform.position.x - SIZE, transform.position.y, transform.position.z);
ChunkBehavior posZNeighbor = tb.GetChunk(transform.position.x, transform.position.y, transform.position.z + SIZE);
ChunkBehavior negZNeighbor = tb.GetChunk(transform.position.x, transform.position.y, transform.position.z - SIZE);
for (int x = 0; x < SIZE; x++) {
for (int y = 0; y < SIZE; y++) {
for (int z = 0; z < SIZE; z++) {
if (blocks[x, y, z] != null) {
bool needsCollision = false;
if (y == SIZE - 1) {
if (topNeighbor != null) {
if (!topNeighbor.BlocksVew(x, 0, z)) {
blocks[x, y, z].CreateTopFace(vertices, triangles);
needsCollision = true;
}
} else {
blocks[x, y, z].CreateTopFace(vertices, triangles);
needsCollision = true;
}
} else if (blocks[x, y + 1, z] == null) {
blocks[x, y, z].CreateTopFace(vertices, triangles);
needsCollision = true;
}
if (y == 0) {
if (bottomNeightbor != null && !bottomNeightbor.BlocksVew(x, SIZE - 1, z)) {
blocks[x, y, z].CreateBottomFace(vertices, triangles);
needsCollision = true;
}
} else if (blocks[x, y - 1, z] == null) {
blocks[x, y, z].CreateBottomFace(vertices, triangles);
needsCollision = true;
}
if (x == SIZE - 1) {
if (posXNeighbor != null && !posXNeighbor.BlocksVew(0, y, z)) {
blocks[x, y, z].CreatePosXFace(vertices, triangles);
needsCollision = true;
}
} else if (blocks[x + 1, y, z] == null) {
blocks[x, y, z].CreatePosXFace(vertices, triangles);
needsCollision = true;
}
if (x == 0) {
if (negXNeighbor != null && !negXNeighbor.BlocksVew(SIZE - 1, y, z)) {
blocks[x, y, z].CreateNegXFace(vertices, triangles);
needsCollision = true;
}
} else if (blocks[x - 1, y, z] == null) {
blocks[x, y, z].CreateNegXFace(vertices, triangles);
needsCollision = true;
}
if (z == SIZE - 1) {
if (posZNeighbor != null && !posZNeighbor.BlocksVew(x, y, 0)) {
blocks[x, y, z].CreatePosZFace(vertices, triangles);
needsCollision = true;
}
} else if (blocks[x, y, z + 1] == null) {
blocks[x, y, z].CreatePosZFace(vertices, triangles);
needsCollision = true;
}
if (z == 0) {
if (negZNeighbor != null && !negZNeighbor.BlocksVew(x, y, SIZE - 1)) {
blocks[x, y, z].CreateNegZFace(vertices, triangles);
needsCollision = true;
}
} else if (blocks[x, y, z - 1] == null) {
blocks[x, y, z].CreateNegZFace(vertices, triangles);
needsCollision = true;
}
/* Don't create collision until we've fixed this problem.
if (needsCollision) {
BoxCollider newBoxCollider = gameObject.AddComponent<BoxCollider>();
newBoxCollider.center = new Vector3(x + .5f, y + .5f, z + .5f);
}*/
}
}
}
}
mesh = new Mesh();
mesh.vertices = vertices.ToArray();
mesh.triangles = triangles.ToArray();
mesh.RecalculateNormals();
GetComponent<MeshFilter>().mesh = mesh;
}
```

**Answer** by Bunny83
·
Apr 17, 2018 at 04:25 AM

ElementAddr_3_8 is the internal method to calculate the flattend array index for your multidimensional array. Since you have a lot array accesses inside the inner most loop you will of course get a lot of these.

You can eliminate some of them by caching the current block at the start of your innermost loop. However for preformance it would be better to use a one dimensional flattend array yourself. Multidimensional arrays are quite slow. When you manually flatten the array you can calculate the intermediate offsets before each nested loop so the index calculation would get simpler.

Though those pure number crunching stuff you may want to carry out on a seperate thread. Just prepare all data required on the main thread and then start the generation. Of course the actual final Mesh creation has to be done on the main thread again.

Alright. I'll try the array flattening and I'll have to look into the upcoming Unity C# job system or multithreading. Thanks for the quick response! It was killing me to know what ElementAddr_3_8 was.

### Your answer

### Welcome to Unity Answers

The best place to ask and answer questions about development with Unity.

To help users navigate the site we have posted a site navigation guide.

If you are a new user to Unity Answers, check out our FAQ for more information.

Make sure to check out our Knowledge Base for commonly asked Unity questions.

If you are a moderator, see our Moderator Guidelines page.

We are making improvements to UA, see the list of changes.

### Follow this Question

### Related Questions

Frame Rate drops when creating mesh in mobile Voxel World? 0 Answers

Is there a Per-Mesh-Profiler somewhere? 2 Answers

How do you handle water in voxel games? 0 Answers

Issues with profiler? 0 Answers

Size of a mesh vs performance 1 Answer