C# 中迭代​​树的微优化

2023-12-06

我正在研究一个massive数字处理项目。从一开始我就一直在优化一切,因为我知道这很重要。在进行性能分析时,我的代码几乎 40% 的生命时间都花在一个函数上——二叉树迭代器。

        public ScTreeNode GetNodeForState(int rootIndex, float[] inputs)
        {
0.2%        ScTreeNode node = RootNodes[rootIndex].TreeNode;

24.6%       while (node.BranchData != null)
            {
0.2%            BranchNodeData b = node.BranchData;
0.5%            node = b.Child2;
12.8%           if (inputs[b.SplitInputIndex] <= b.SplitValue)
0.8%                node = b.Child1;
            }

0.4%        return node;
        }

C# 优化专家是否有任何进一步优化的建议?所有比较都是浮动的。我知道理论上这应该不重要,但我使用的是字段而不是属性,因此可以确保优化。这里节省一点点就可以缩短流程几天。

请不要回复说“这些优化在现实世界中并不重要”——因为在这种情况下它们确实重要。 :-)

编辑:我已按照下面的注释将代码更新为现在的代码,并添加到每行代码的性能分析输出中。正如您所看到的,主要杀手是空检查 - 为什么?我尝试在节点上使用布尔标志 IsLeaf 而不是空检查,但该行的性能受到同等影响。

分支节点对象的代码如下:

public sealed class BranchNodeData
{
    /// <summary>
    /// The index of the data item in the input array on which we need to split
    /// </summary>
    internal int SplitInputIndex = 0;

    /// <summary>
    /// The value that we should split on
    /// </summary>
    internal float SplitValue = 0;

    /// <summary>
    /// The nodes children
    /// </summary>
    internal ScTreeNode Child1;
    internal ScTreeNode Child2;
}

另一个编辑:这里还有更多的思考......我想知道为什么这条线

BranchNodeData b = node.BranchData;

记录了执行的 0.2%,空比较行记录了 17.7%。我猜这是分支预测失败?虽然该比较被多次命中,并且几乎总是返回 true,但这使得 CPU 很难预测它何时会返回 false。我不太了解 CPU 的低级工作原理,但情况可能是这样吗?


只是重写一些代码。这可能会有所帮助,因为它至少避免了两次跳跃。

public ScTreeNode GetNodeForState(int rootIndex, float[] inputs)
{

    ScTreeNode node = RootNodes[rootIndex].TreeNode;

    while (node.BranchData != null)
    {
        BranchNodeData b = node.BranchData;
        node = b.Child2;
        if (inputs[b.SplitInputIndex] <= b.SplitValue))
            node = b.Child1;
    }

    return node;

}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C# 中迭代​​树的微优化 的相关文章

随机推荐

  • 通过单击 WinForms 中的按钮在面板上绘图

    我正在尝试制作一个程序来绘制Panel 正方形 圆形等 通过单击按钮 到目前为止我还没有做太多事情 只是尝试将代码直接绘制到面板上 但不知道如何将其移动到按钮上 这是我到目前为止的代码 如果您知道比我正在使用的方法更好的绘制方法 请告诉我
  • 使用默认用户帐户以编程方式发送电子邮件

    我希望能够根据用户按下我的应用程序活动上的按钮从我的应用程序发送电子邮件 应用程序需要在按下按钮时自动发送电子邮件 即我不想向用户显示另一个电子邮件表单 并且应该发送电子邮件使用用户手机上的默认电子邮件帐户不是我硬编码到我的应用程序中的电子
  • 如何使用csc(C#编译器)或dmcs(mono C#编译器)生成IL源代码?

    gcc 有一个 s 选项来生成汇编源代码 csc MS C 编译器 或 dmcs mono C 编译器 是否等效 我的意思是 这些编译器是否提供了一个选项来生成可以读取而不是执行二进制文件的 IL 源代码 到达 IL 非常容易 只需使用il
  • Spark结构化流仅从Kafka的一个分区获取消息

    我遇到了这样一种情况 spark 只能从 Kafka 2 分区主题的一个分区进行流式传输和获取消息 我的主题 C bigdata kafka 2 11 0 10 1 1 bin windows gt kafka topics create
  • 如何在选定区域打开相机活动

    每个身体 我是 Android 世界的新手 所以我需要你的帮助 我想知道我们如何在选定区域打开相机活动 以这样的方式 AS 在下面给出的屏幕截图中 不一定要在圆形区域中打开 在我的应用程序中 我可以在任何自定义区域中打开 可以是圆形 矩形或
  • 在Scheme中柯里化一个函数n次

    我无法找到一种将函数柯里化指定次数的方法 也就是说 我给函数一个自然数 n 和一个函数 fun 并且它对函数进行柯里化 n 次 例如 curry n fun 该功能和可能的应用程序是 curry 4 1 2 3 4 这将产生 10 我真的不
  • 将文本转换为 PDF

    我有一大串文本 显然是 PDF 文件的原始数据 我需要将其重新转换为 PDF 目前 我正在将字符串读入 StringBuffer 但如果需要 我可以更改它 从那里我尝试将其写入文件并更改扩展名 我真的希望这能起作用 但我有点知道它不会 我尝
  • GDB断点后如何恢复指令

    我读到 GDB 将 int 3 操作码 CC 放在目标程序内存中的所需地址处 Si这个操作是擦除程序存储器中的一条指令 1字节 我的问题是 当程序继续时 GDB 如何以及何时替换原始操作码 当我在 GDB 中输入 disassemble 时
  • Java 8 Update 71 后 Eclipse Mars 无法启动

    我昨天安装了 Java 8 Update 71 但之后我的 Eclipse 无法启动 Windows 仅在鼠标上显示一个简短的加载符号 仅此而已 在我使用 Java 8 Update 66 之前 一切都运行良好 所以我尝试用 clean参数
  • 如何找到下一个工作日:MATLAB

    鉴于日期 20170203 yyyymmdd 我如何找到下一个工作日 即本例中的 20170206 date datenum 20170203 yyyymmdd NBD nextBusinessDay date NBD 06 Feb 201
  • 绝对定位的容器不会扩展宽度以适应弹性盒内容[重复]

    这个问题在这里已经有答案了 我有一个flexbox在绝对定位的父级内部div 我期望flexbox有一个computed width 导致父 div 展开 但这不会发生 父 div 有一定的宽度 但不足以容纳 Flexbox 鉴于 Flex
  • 无法正确绑定 observables 的 observableArray

    我有以下代码应该绑定 observables 的 observableArray
  • Selenium 和 ChromeDriver:会话未创建,无法连接到渲染器

    我正在尝试通过 Mac 上的 Webdriver io Selenium 和 ChromeDriver 运行自动化测试 我正在使用所有相关软件的最新版本 硒3 9 1 Chrome 驱动程序 2 35 铬64 操作系统 macOS High
  • 如何在 iframe 内引用 iframe

    我想引用另一个 iframe 内的 iframe div class playButton Play div div class flex active slide document document div
  • 从 HashSet 中选取“任何”项目非常慢 - 如何快速做到这一点?

    我目前正在使用贪婪算法做很多工作 它们不关心索引等 它们只适用于组 集合 但我发现 85 的执行时间都花在尝试从 HashSet 中选择一个项目上 根据 MSDN 文档 HashSet 类提供高性能的集合操作 一套 是一个不包含重复元素的集
  • 复制/移动未实现复制的字段

    费里斯船长有一张地图 seven seas png 他隐藏了多个宝藏的区域 在坐标 5 7 和 7 9 处 他想为每件宝藏创建一个单独的藏宝图 原始地图不应更改 他决定使用 Rust 和图像箱为了这 extern crate image u
  • 带参数的 .html 漂亮 URL

    我有一个网站 仅包含 html前端 我想要漂亮的 URL 我的目标是创造这样的东西 http test com mypage html gt http test com mypage http test com mypage1 html g
  • Web 组件/HtmlElement:单元测试

    我正在尝试测试一个网络组件 这是我的项目结构 package json src app js index html test hello world test html 这是我的工作代码 class HelloWorld extends H
  • C# 并排合并两个或多个文本文件

    using StreamWriter writer File CreateText FinishedFile int lineNum 0 while lineNum lt FilesLineCount Min for int i 0 i l
  • C# 中迭代​​树的微优化

    我正在研究一个massive数字处理项目 从一开始我就一直在优化一切 因为我知道这很重要 在进行性能分析时 我的代码几乎 40 的生命时间都花在一个函数上 二叉树迭代器 public ScTreeNode GetNodeForState i