如何解读BenchmarkDotNet和dotMemory的结果? [英] How to interpret the results from BenchmarkDotNet and dotMemory?

查看:93
本文介绍了如何解读BenchmarkDotNet和dotMemory的结果?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

因此,我的Main()方法中有以下一段代码

for (int x = 0; x < 100; x++) // to mimic BenchmarkDotnet runs
   for (int y = 0; y < 10000; y++)
     LogicUnderTest();

接下来,我测试了以下类

[MemoryDiagnoser, ShortRunJob]
public class TestBenchmark
{
    [Benchmark]
    public void Test_1()
    {
        for (int i = 0; i < 10000; i++)
            LogicUnderTest();
    }
}

dotMemory下运行Main()大约6分钟后,我收到以下结果

应用程序从10Mb开始,一直到14Mb

但是,当我运行BenchmarkDotnet测试时,我得到以下结果

我看到我已经分配了2.6GB。什么?看起来一点都不好。此外,我看不到Gen1Gen2列。这是否意味着代码没有在它们中分配任何内容,所以没有显示任何内容?

我如何解释结果?在DotMemory中似乎完全可以,但在BenchmarkDotNet中则不能。我是BenchmarkDotnet的新手,如果有任何有关结果的信息,我会很有帮助的。

PS。LogicUnderTest()广泛使用字符串。

PSS。粗略地说,LogicUnderTest是这样实现的

void LogicUnderTest()
{
    var dict = new Dictionary<int, string>();
    for (int j = 0; j < 1250; j++)
        dict.Add(j, $"index_{j}");
    string.Join(",", dict.Values);
}

推荐答案

我是MemoryDiagnoser的作者,我也在我的blog上为您的问题提供了答案。我只会复制到这里:

如何阅读结果

|     Method |  Gen 0 | Allocated |
|----------- |------- |---------- |
|          A |      - |       0 B |
|          B |      1 |     496 B |
  • 已分配包含已分配的托管内存的大小。不包括堆栈分配/本机堆分配。它针对单个调用,包含
  • Gen X列包含每个1 000操作的Gen X集合数量。如果该值等于1,则意味着GC在第X中每1000次基准调用收集一次内存。BenchmarkDotNet在运行基准测试时使用了一些启发式方法,因此对于不同的运行,调用的次数可能不同。缩放使结果具有可比性。
  • Gen列中的-表示未执行垃圾回收。
  • 如果Gen X列不存在,则表示第X代没有执行垃圾回收。如果您的基准都没有诱导GC,则不存在Gen列。

阅读结果时请记住:

  • 1 kB=1 024字节
  • 每个引用类型实例都有两个额外的字段:对象头和方法表指针。这就是为什么每个对象分配的结果总是包含2倍的指针大小。有关额外开销的更多详细信息,请阅读Konrad Kokosa的这篇博文How does Object.GetType() really work?
  • CLR执行一些对齐操作。如果您尝试分配new byte[7]数组,它将分配byte[8]数组。

这篇关于如何解读BenchmarkDotNet和dotMemory的结果?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆