Ric*_*y G 9 .net c# performance benchmarking .net-core
我正在使用 funcs 将重复的算术代码移动到可重用的块中,但是当我运行一个简单的测试来测试它是否会更慢时,我很惊讶它的速度是原来的两倍。
为什么计算表达式的速度要慢两倍
using System;
using System.Runtime.CompilerServices;
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Exporters;
using BenchmarkDotNet.Loggers;
using BenchmarkDotNet.Running;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
var summary = BenchmarkRunner.Run<Calculations>();
var logger = ConsoleLogger.Default;
MarkdownExporter.Console.ExportToLog(summary, logger);
Console.WriteLine(summary);
}
}
public class Calculations
{
public Random RandomGeneration = new Random();
[Benchmark]
public void CalculateNormal()
{
var s = RandomGeneration.Next() * RandomGeneration.Next();
}
[Benchmark]
public void CalculateUsingFunc()
{
Calculate(() => RandomGeneration.Next() * RandomGeneration.Next());
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public int Calculate(Func<int> expr)
{
return expr();
}
}
}
Run Code Online (Sandbox Code Playgroud)
Jon*_*eet 14
您在每次调用时都创建一个新的委托对象。这并不奇怪,它有相当多的开销。
如果您使用不捕获this或任何局部变量的 lambda 表达式(在这种情况下编译器可以将其缓存在静态字段中),或者如果您显式创建单个实例并将其存储在自己的字段中,则大部分开销消失了。
这是您的测试的修改版本:
public class Calculations
{
public Random RandomGeneration = new Random();
private Func<int> exprField;
public Calculations()
{
exprField = () => RandomGeneration.Next() * RandomGeneration.Next();
}
[Benchmark]
public void CalculateNormal()
{
var s = RandomGeneration.Next() * RandomGeneration.Next();
}
[Benchmark]
public void CalculateUsingFunc()
{
Calculate(() => RandomGeneration.Next() * RandomGeneration.Next());
}
[Benchmark]
public void CalculateUsingFuncField()
{
Calculate(exprField);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public int Calculate(Func<int> expr)
{
return expr();
}
}
Run Code Online (Sandbox Code Playgroud)
我机器上的结果:
| Method | Mean | Error | StdDev |
|------------------------ |---------:|---------:|---------:|
| CalculateNormal | 27.61 ns | 0.438 ns | 0.388 ns |
| CalculateUsingFunc | 48.74 ns | 1.009 ns | 0.894 ns |
| CalculateUsingFuncField | 32.53 ns | 0.698 ns | 0.717 ns |
Run Code Online (Sandbox Code Playgroud)
所以仍然有一些开销,但比以前少了很多。
| 归档时间: |
|
| 查看次数: |
590 次 |
| 最近记录: |