Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WorldRenderer, replace ActorsWithTraits with ApplyToActorsWithTrait. #19557

Merged
merged 1 commit into from Mar 13, 2022

Conversation

anvilvapre
Copy link
Contributor

Closes #18798.

At least 2 to 4.2 times less ticks are used - by avoiding the allocation of Trait Actor pairs that use generics.

I.e. 2442 ticks before, 571 ticks after.

reaperrr
reaperrr previously approved these changes Jul 24, 2021
Copy link
Contributor

@reaperrr reaperrr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Didn't notice any issues

Comment on lines 290 to 291
World.ApplyToActorsWithTrait<IRenderShroud>((Actor actor, IRenderShroud trait) =>
trait.RenderShroud(this));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
World.ApplyToActorsWithTrait<IRenderShroud>((Actor actor, IRenderShroud trait) =>
trait.RenderShroud(this));
World.ApplyToActorsWithTrait<IRenderShroud>((Actor actor, IRenderShroud trait) => trait.RenderShroud(this));

@abcdefg30
Copy link
Member

Did you measure the impact of #18798 (comment) (Action delegate allocations)?

@anvilvapre
Copy link
Contributor Author

Did you measure the impact of #18798 (comment) (Action delegate allocations)?

Not in exact numbers. However there is an significant overhead. ActorsHavingTrait - that returns an enumerator not allocating a pair - is faster than calling a similar Apply function using an action. So enumerations have the preference.

@pchote
Copy link
Member

pchote commented Jul 24, 2021

@teinarss would you be able to do some of your benchmarking tests on this?

@teinarss
Copy link
Contributor

teinarss commented Jul 24, 2021 via email

@anvilvapre
Copy link
Contributor Author

See also #18357 (comment)

@pchote
Copy link
Member

pchote commented Jul 27, 2021

I let the RA shellmap run for 5000 ticks for 3 runs, alternating pr/before/pr/before/pr/before and looked at the render_prepare (which is what calls Generate*Renderables) and also tick_time (on the assumption that any extra GC stalls from the Action allocations are most likely to be visible here).

The before/after results overlap within the scatter of the 3 runs, so there doesn't seem to be any significant impact either way and we can instead consider this on code style/consistency grounds.

@@ -153,14 +153,14 @@ void GenerateRenderables()
// PERF: Avoid LINQ.
void GenerateOverlayRenderables()
{
foreach (var a in World.ActorsWithTrait<IRenderAboveShroud>())
World.ApplyToActorsWithTrait<IRenderAboveShroud>((Actor actor, IRenderAboveShroud trait) =>
Copy link
Member

@pchote pchote Jul 27, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And likewise here.

@@ -195,14 +195,14 @@ void GenerateOverlayRenderables()
// PERF: Avoid LINQ.
void GenerateAnnotationRenderables()
{
foreach (var a in World.ActorsWithTrait<IRenderAnnotations>())
World.ApplyToActorsWithTrait<IRenderAnnotations>((Actor actor, IRenderAnnotations trait) =>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Its not necessary to specify all three types here. This could be either

World.ApplyToActorsWithTrait<IRenderAnnotations>((actor, trait) =>

or

World.ApplyToActorsWithTrait>((Actor actor, IRenderAnnotations trait) =>

IMO the first is easier to read.

foreach (var a in World.ActorsWithTrait<IRenderAboveWorld>())
if (a.Actor.IsInWorld && !a.Actor.Disposed)
a.Trait.RenderAboveWorld(a.Actor, this);
World.ApplyToActorsWithTrait<IRenderAboveWorld>((Actor actor, IRenderAboveWorld trait) =>
Copy link
Member

@pchote pchote Jul 27, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And here, and below.

@penev92
Copy link
Member

penev92 commented Aug 10, 2021

Adding a Fixup requested label because of the above three comments.

@anvilvapre
Copy link
Contributor Author

I let the RA shellmap run for 5000 ticks for 3 runs, alternating pr/before/pr/before/pr/before and looked at the render_prepare (which is what calls Generate*Renderables) and also tick_time (on the assumption that any extra GC stalls from the Action allocations are most likely to be visible here).

The before/after results overlap within the scatter of the 3 runs, so there doesn't seem to be any significant impact either way and we can instead consider this on code style/consistency grounds.

It may also be that on ``dotnetthis makes less of a difference then onmono`.

@abcdefg30 abcdefg30 merged commit 83357af into OpenRA:bleed Mar 13, 2022
@abcdefg30
Copy link
Member

Changelog

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Replace ActorsWithTrait in more location with ApplyToActorsWithTrait
7 participants