Skip to content

Reduce usage of LINQ in constructor selection#18

Merged
jvandertil merged 2 commits intoReflectionMagic:masterfrom
jvandertil:netstandard15-perf
May 29, 2018
Merged

Reduce usage of LINQ in constructor selection#18
jvandertil merged 2 commits intoReflectionMagic:masterfrom
jvandertil:netstandard15-perf

Conversation

@jvandertil
Copy link
Copy Markdown
Collaborator

@jvandertil jvandertil commented May 27, 2018

The current implementation uses a LINQ based approach for selecting a constructor to work around the issue of not having the correct overload for Activator.CreateInstance() available.

This is allocating quite a bit of garbage and is not ideal as can be seen below:

BenchmarkDotNet=v0.10.14, OS=Windows 10.0.17134
Intel Core i7-7700K CPU 4.20GHz (Kaby Lake), 1 CPU, 8 logical and 4 physical cores
.NET Core SDK=2.1.201
  [Host]     : .NET Core 1.1.8 (CoreCLR 4.6.26328.01, CoreFX 4.6.24705.01), 64bit RyuJIT
  DefaultJob : .NET Core 1.1.8 (CoreCLR 4.6.26328.01, CoreFX 4.6.24705.01), 64bit RyuJIT

Method Mean Error StdDev Gen 0 Allocated
DirectConstructorNoArgs 2.872 ns 0.0048 ns 0.0040 ns 0.0172 72 B
NoArgumentsOld 1,631.505 ns 2.1347 ns 1.6666 ns 0.3872 1624 B
NoArgumentsNew 281.524 ns 0.2437 ns 0.2280 ns 0.0587 248 B
SingleArgumentOld 1,765.470 ns 2.6305 ns 2.4606 ns 0.4101 1728 B
SingleArgumentNew 374.443 ns 0.6819 ns 0.5694 ns 0.0782 328 B
TwoArgumentsOld 1,800.418 ns 2.3833 ns 2.2293 ns 0.4177 1752 B
TwoArgumentsNew 460.282 ns 0.2595 ns 0.2427 ns 0.0930 392 B
EightArgumentsOld 2,457.870 ns 1.9476 ns 1.8218 ns 0.5226 2208 B
EightArgumentsNew 945.033 ns 6.9714 ns 5.8215 ns 0.2222 936 B

This represents a 200-600% increase of performance and a likewise reduction of allocations. Using reflection remains slow ofcourse.

Also fixes #19.

@jvandertil jvandertil added this to the 3.2.0 milestone May 27, 2018
@jvandertil jvandertil force-pushed the netstandard15-perf branch from 47425c8 to dfa4e70 Compare May 27, 2018 11:48
Improves performance in benchmarks by 200-600%
@jvandertil jvandertil force-pushed the netstandard15-perf branch from dfa4e70 to 7f05609 Compare May 27, 2018 11:50
Improves performance by roughly 6%
@jvandertil
Copy link
Copy Markdown
Collaborator Author

jvandertil commented May 27, 2018

Removing the intermediate array improves allocations and run time slightly (~5%).

BenchmarkDotNet=v0.10.14, OS=Windows 10.0.17134
Intel Core i7-7700K CPU 4.20GHz (Kaby Lake), 1 CPU, 8 logical and 4 physical cores
.NET Core SDK=2.1.201
  [Host]     : .NET Core 1.1.8 (CoreCLR 4.6.26328.01, CoreFX 4.6.24705.01), 64bit RyuJIT
  DefaultJob : .NET Core 1.1.8 (CoreCLR 4.6.26328.01, CoreFX 4.6.24705.01), 64bit RyuJIT

Method Mean Error StdDev Gen 0 Allocated
DirectConstructorNoArgs 3.319 ns 0.0288 ns 0.0256 ns 0.0172 72 B
NoArgumentsOld 263.208 ns 0.0863 ns 0.0720 ns 0.0587 248 B
NoArgumentsNew 259.217 ns 0.3422 ns 0.3201 ns 0.0534 224 B
SingleArgumentOld 353.958 ns 0.7980 ns 0.7464 ns 0.0782 328 B
SingleArgumentNew 342.360 ns 0.9554 ns 0.8937 ns 0.0701 296 B
TwoArgumentsOld 439.770 ns 0.4104 ns 0.3639 ns 0.0930 392 B
TwoArgumentsNew 415.774 ns 0.3067 ns 0.2718 ns 0.0834 352 B
EightArgumentsOld 919.081 ns 0.9206 ns 0.8611 ns 0.2222 936 B
EightArgumentsNew 871.048 ns 1.3827 ns 0.9998 ns 0.2022 848 B

Copy link
Copy Markdown
Collaborator

@davidebbo davidebbo left a comment

Choose a reason for hiding this comment

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

Nice perf analysis!

Though I'm a bit surprised that the LINQ code would be that much more inefficient. It seems that it should be making roughly the same calls. But I guess the numbers don't lie :)

@jvandertil jvandertil merged commit 0c05d01 into ReflectionMagic:master May 29, 2018
@jvandertil jvandertil deleted the netstandard15-perf branch May 29, 2018 19:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Projects targetting .NET Standard 2.0 use slow constructor selection

2 participants