Using lambdas have initial startup cost?

Hello,

I hope I can describe my problem generally because I haven't been able to shorten my code enough just yet to fit inside a forum post.

I have a ranged loop that draws an OpenGL scene via iterating a vector of objects and calls the respective draw functions.

Also inside this loop are "static const auto" lamdas that check whether objects need to be deleted in cases which the aforementioned objects go too far out of the scene.

Here is a snippet:

1
2
3
4
5
6
7

static const auto is_erasable = [&](PhysicsObject* p) { return p->GetCurrentPosition()->y < LowestYValueAllowed; };

CurrentOpaqueObjects.erase(std::remove_if(CurrentOpaqueObjects.begin(), CurrentOpaqueObjects.end(), is_erasable), CurrentOpaqueObjects.end());

CurrentTransparentObjects.erase(std::remove_if(CurrentTransparentObjects.begin(), CurrentTransparentObjects.end(), is_erasable), CurrentTransparentObjects.end());


The problem I have is that when I have this code active my OpenGL drawing is initially EXTREMELY slow; one FULL second per frame if not more.

Then, after waiting 15-30 seconds, depending on the size of the scene, everything speeds up and the loop speed returns to a decent speed.

Disabling this code allows the scene to draw fast even when I first start up the scene.

Anyone can guess why that is?

Any resolution?

I hope what I wrote makes sense.
Do you mean just turning the lambda into a named function reference? Or removing the erase/removes as well? Because removing the erase/removes will save lots of time on your loops; it probably would speed up once it stops having to remove things.
Well, I know this may be hard to do without seeing my code but what I am looking for is the best way to be able to remove objects that fall out of scope of the scene without slowing down the drawing of the scene itself too much (I understand there will be some penalty for this, just want it as minimal as possible).

Currently I use a ranged loop for looping through all of the objects for the OpenGL draws.

I was actually surprised that the erase functions slowed down the program so much, I used to have a traditional for loop along these lines and I experienced much less slowdown:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
for (std::vector<PhysicsObject*>::iterator it = CurrentTransparentObjects.begin(); it != CurrentTransparentObjects.end(); /* This section of loop intentionally left out. */)
{

	(*it)->CalculatePhysicsOrientation();

	(*it)->DrawMe();

	glm::vec3* CurrentBoxPosition = (*it)->GetCurrentPosition();

	if (CurrentBoxPosition->y < LowestYValueAllowed) {

		delete (*it);

		it = CurrentTransparentObjects.erase(it);

	}

	else ++it;

}
The reason why I switched to the ranged loop was because it was simpler and faster to write that code.

But now introducing the lambdas with the erase/remove_if algorithems slowed things down.

I am not sure what to do to speed things up again without slipping back to old/bad c++ code.

Any ideas?
This is how my ranged loops look like:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

for (auto & e : CurrentOpaqueObjects) {

	e->CalculatePhysicsOrientation();

	e->DrawMe();

}

for (auto & e : CurrentTransparentObjects) {

	e->CalculatePhysicsOrientation();

	e->DrawMe();

}


With just this code, everything runs great.

But now I need to delete objects out of the CurrentOpaqueObjects and CurrentTransparentObjects vectors when their positions go outside of the scene.
Last edited on
Do not use default capture modes. YOu are saving references to all variables context into lambda function. And then you are passing it by copy. Depending on amount of visible locals, you can easily have > 100 bytes copying around.
You need to capture only one variable:
1
2
static const auto is_erasable = [LowestYValueAllowed](PhysicsObject* p) 
                { return p->GetCurrentPosition()->y < LowestYValueAllowed; };
You may capture LowestYValueAllowed by reference if can change during execution.
Last edited on
Topic archived. No new replies allowed.