Skip to content

Conversation

@gfoidl
Copy link
Member

@gfoidl gfoidl commented Feb 21, 2018

Continuation from #314 (comment)

Description

I tried several things to "devirtualize" the calls to IPooledObjectPolicy

On this I focused on the perf of Return, as this is a common case.
Create is cold, so I didn't investigate it, although the same optimization are applied.

The above mentioned tries results in (Default is the state after merging #314), done with benchmarks that use StringBuilderPooledObjectPolicy.

BenchmarkDotNet=v0.10.12, OS=Windows 10 Redstone 3 [1709, Fall Creators Update] (10.0.16299.248)
Intel Core i7-7700HQ CPU 2.80GHz (Kaby Lake), 1 CPU, 8 logical cores and 4 physical cores
Frequency=2742187 Hz, Resolution=364.6724 ns, Timer=TSC
.NET Core SDK=2.1.4
  [Host]     : .NET Core 2.0.5 (Framework 4.6.26020.03), 64bit RyuJIT
  DefaultJob : .NET Core 2.0.5 (Framework 4.6.26020.03), 64bit RyuJIT

Method Mean Error StdDev Scaled
Default 28.11 ns 0.2196 ns 0.2054 ns 1.00
NoInterface 21.75 ns 0.1348 ns 0.1261 ns 0.77
Expressions 23.38 ns 0.1760 ns 0.1646 ns 0.83
DynamicMethod 21.92 ns 0.3097 ns 0.2897 ns 0.78

Code for benchmark.

For completeness the results with Original before merging #314:

BenchmarkDotNet=v0.10.12, OS=Windows 10 Redstone 3 [1709, Fall Creators Update] (10.0.16299.248)
Intel Core i7-7700HQ CPU 2.80GHz (Kaby Lake), 1 CPU, 8 logical cores and 4 physical cores
Frequency=2742187 Hz, Resolution=364.6724 ns, Timer=TSC
.NET Core SDK=2.1.4
  [Host]     : .NET Core 2.0.5 (Framework 4.6.26020.03), 64bit RyuJIT
  DefaultJob : .NET Core 2.0.5 (Framework 4.6.26020.03), 64bit RyuJIT

Method Mean Error StdDev Scaled
Original 34.14 ns 0.4016 ns 0.3756 ns 1.00
Default 29.24 ns 0.1374 ns 0.1285 ns 0.86
NoInterface 21.92 ns 0.2210 ns 0.2068 ns 0.64
Expressions 23.43 ns 0.1165 ns 0.1089 ns 0.69
DynamicMethod 21.80 ns 0.1269 ns 0.1187 ns 0.64

Discussion

Abstract base class

This variant requires an abstract base class
and to take advantage of, the PoolProvider-classes have to be adapted. This isn't ideal, because there may be classes out in the wild the can't be updated or this takes a lot of effort to update all classes on several places.

Therefore this variant is discontinued, although perf is super.

Expression

Expressions compiled to delegates incur a security check at runtime, that can be clearly seen in the numbers --> discontinued.

IL code gen

  • Delegates from dynamic method can be associated with an owner, so be security runtime check doesn't occur.
  • Perf is on par with the abstract class variant.
  • All existing PoolProvider implementations benefit from this variant without touching the implementation. This is a huge benefit, because they get the improvement for free. Therefore this variant is reflected in the code of this PR.
  • The cost for creating / compiling the delegates shouldn't matter, because this is done once at initialization.

Combination of abstract class and IL code gen

As prototype I tried a combination of the approach with abstract base class, and when the PoolProvider does just implement the interface (not the base class), so per fallback IL code is generated.

Here the perf is on par with the two others, so no real win. Because of code complexity this variant is discontinued and not checked in the repo -- I just prototyped it.

@gfoidl
Copy link
Member Author

gfoidl commented Feb 21, 2018

/cc @rynowak

</PropertyGroup>

<ItemGroup>
<PackageReference Include="System.Reflection.Emit.Lightweight" Version="4.3.0" />
Copy link
Member

Choose a reason for hiding this comment

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

I'm not sure we want this type of dependency in the object pool.

Copy link
Member Author

Choose a reason for hiding this comment

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

OK. So in this case take the variant with the abstract base class?

Copy link
Member Author

Choose a reason for hiding this comment

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

The variant with the abstract base class -> #318

@gfoidl
Copy link
Member Author

gfoidl commented Feb 21, 2018

Ups, I had a copy & paste error in the description, so I update it.

error KRB4005: PackageReference must use an MSBuild variable to set the version.
@rynowak
Copy link
Member

rynowak commented Feb 21, 2018

Thanks for trying and sharing this, it's pretty cool. I think we'd definitely look to avoid this level of complexity for something like this. Closing this out in favor of your other PR.

@rynowak rynowak closed this Feb 21, 2018
@gfoidl gfoidl deleted the objectpool-devirt branch February 21, 2018 16:27
@ghost ghost locked as resolved and limited conversation to collaborators May 30, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants