Nyrest / FastGenericNew

The ultimate fast alternative to Activator.CreateInstance<T> / new T()
MIT License
235 stars 9 forks source link

First Run is slow #16

Closed JeffBusterCase closed 2 years ago

Nyrest commented 2 years ago

Hi. thanks for the comment.

In most cases, we can only choose one of first-run speed and post-run speed on a managed platform. However. using ILEmit instead of Expression can shorten the first run time a bit. But this will need an overhaul of the entire library.

I'll try it tomorrow.

JeffBusterCase commented 2 years ago

Maybe adding a Initialization? I don't know if this is possible.... Before a project is run.?

Nyrest commented 2 years ago

Maybe adding a Initialization? I don't know if this is possible.... Before a project is run.?

I think it can't be a solution. You just moved that 1ms to elsewhere but it won't change the fact that it took 1ms.

JeffBusterCase commented 2 years ago

This one displays the ~sad~ gap even more: image

Nyrest commented 2 years ago

This one displays the ~sad~ gap even more: image

Can you provide the source code so I can reproduce this?

JeffBusterCase commented 2 years ago

Here: https://github.com/JeffBusterCase/BenchmarkFastNewManually

Nyrest commented 2 years ago

Here: JeffBusterCase/BenchmarkFastNewManually

Thanks. I see the code and I think there are some issues with the measuring.

First, you shouldn't benchmark them in parallel. It's because two or more threads can be assigned to the same CPU core and they will be certainly slower than others. You should benchmark them one by one instead.

And you should use Stopwatch instead of DateTime.

Stopwatch automatically checks for the existence of high-precision timers. It is worth mentioning that DateTime.Now often is quite a bit slower than DateTime.UtcNow due to the work that has to be done with timezones, DST and such. DateTime.UtcNow typically has a resolution of 15 ms. See John Chapman's blog post about DateTime.Now precision for a great summary.

https://stackoverflow.com/questions/28637/is-datetime-now-the-best-way-to-measure-a-functions-performance

It's recommended to use Benchmark.NET https://benchmarkdotnet.org/articles/overview.html

JeffBusterCase commented 2 years ago

I updated the code to better match the correct benchmark, but still... the initialization is what kills the objective :( https://github.com/JeffBusterCase/BenchmarkFastNewManually image

On the last 2 lines: FastNew[NoInit] takes 8x times more time than Common (The two of them on 60k iterations)

Nyrest commented 2 years ago

This issue is delayed to 3.2.0 due I found a solution that better than ILGenerator. https://github.com/Nyerst/FastGenericNew/pull/19

Nyrest commented 2 years ago

Solved in #19 you can enable FastGenericNew.SourceGenerator to call GetActivationInfo by adding this to the project file

<PropertyGroup>
    <FastNew_AllowUnsafeImplementation>true</FastNew_AllowUnsafeImplementation>
</PropertyGroup>
JeffBusterCase commented 2 years ago

Sorry, I didn't understand.. Shouldn't this be a 'official' fix instead of a workaround/option..... How can I test on my project witthout the Nuget Version (Still on 3.1.0-preview)

Nyrest commented 2 years ago

Sorry, I didn't understand.. Shouldn't this be a 'official' fix instead of a workaround/option..... How can I test on my project witthout the Nuget Version (Still on 3.1.0-preview)

This is an 'official' fix. the new implementation is stable now after working on it. You can see how this library work now by checking the generated code: https://github.com/Nyerst/FastGenericNew/tree/main/FastGenericNew/_generated/FastGenericNew.SourceGenerator/FastGenericNew.SourceGenerator.Generator

The reason why this is an option is that it's slower than the classic FastNew which defeats the purpose of this library

v3.2.0 is not released yet because there are still some minor jobs for the Unit Test project to do. For now, you can try v3.2.0 by cloning this repo and compiling it. Note that you will need .NET 7 SDK to compile this library.

You can reproduce the Benchmark by running the FastGenericNew.Benchmarks project.