- 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 t$$anonymous$$s 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 cac$$anonymous$$ng 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 crunc$$anonymous$$ng 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

If you’re new to Unity Answers, please check our User Guide to help you navigate through our website and refer to our FAQ for more information.

Before posting, make sure to check out our Knowledge Base for commonly asked Unity questions.

Check our Moderator Guidelines if you’re a new moderator and want to work together in an effort to improve Unity Answers and support our users.

### Follow this Question

### Related Questions

Size of a mesh vs performance 1 Answer

Mesh Collider for Voxels 1 Answer

How do you handle water in voxel games? 0 Answers

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

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